Skip to content

Commit

Permalink
refactor: rio parsing (#13)
Browse files Browse the repository at this point in the history
  • Loading branch information
cmdoret authored and supermaxiste committed Jun 24, 2024
1 parent 0d08fdb commit cb9b7eb
Show file tree
Hide file tree
Showing 6 changed files with 120 additions and 59 deletions.
34 changes: 34 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,7 @@ slog-async = "2.8.0"
# Popular serialization library.
serde = { version = "1.0", features = ['derive']}
clap = { version = "4.5.7", features = ["derive"] }
rio_turtle = "0.8.4"
rio_api = "0.8.4"
bitflags = "2.5.0"
serde_yml = "0.0.10"
9 changes: 5 additions & 4 deletions src/io.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use crate::{model::Triple, rules::Config};
use crate::rules::Config;

use serde_yml;

use rio_turtle::NTriplesParser;
use std::{
fs::File,
io::{BufRead, BufReader},
iter::Iterator,
path::Path,
};

Expand All @@ -16,8 +17,8 @@ pub fn get_buffer(path: &Path) -> BufReader<File> {
}

// Parse RDF triples.
pub fn parse_ntriples(reader: Box<dyn BufRead>) -> impl Iterator<Item = Triple> {
return reader.lines().map(|l| Triple::parse_ntriples(&l.unwrap()));
pub fn parse_ntriples(reader: Box<dyn BufRead>) -> NTriplesParser<Box<dyn BufRead>> {
return NTriplesParser::new(reader);
}

// Parse yaml configuration file.
Expand Down
2 changes: 1 addition & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use crate::{
};

use clap::{Args, Parser, Subcommand};
use std::{fs::File, io::BufReader, path::PathBuf};
use std::path::PathBuf;

#[derive(Parser)]
#[command(name = "rdf-protect")]
Expand Down
108 changes: 60 additions & 48 deletions src/model.rs
Original file line number Diff line number Diff line change
@@ -1,62 +1,74 @@
use crate::crypto::hash;
use bitflags::bitflags;

#[derive(Debug)]
pub struct Triple {
pub subject: String,
pub predicate: String,
pub object: String,
use bitflags;
use rio_api::model::{Subject, Term, Triple};

pub trait Pseudonymize {
fn pseudo(&self) -> Self;
}

// should use bitflags, e.g. S = 0b100, P = 0b010 -> SP = S + P
bitflags! {
pub struct TriplePart: u8 {
const SUBJECT = 1 << 0;
// Used to select any combination of fields in a triple
bitflags::bitflags! {
#[derive(Debug, Copy, Clone)]
pub struct TripleMask: u8 {
const SUBJECT = 1 << 2 ;
const PREDICATE = 1 << 1;
const OBJECT = 1 << 2;
const OBJECT = 1 << 0;
}
}

impl TriplePart {
// Checks if a all bits in `mask` are set.
fn is_set(&self, mask: TriplePart) -> bool {
return self.bits() & mask.bits() == mask.bits();

impl TripleMask {

// Checks if bit from another mask are all set in this mask
pub fn is_set(&self, other: &TripleMask) -> bool {

return (*other - *self).bits() != 0;
}

}

impl Triple {
pub fn new(subject: String, predicate: String, object: String) -> Triple {
Triple {
subject,
predicate,
object,
}
}
// Pseudonymize parts of a triple set by its mask
pub fn pseudonymize_triple<'a>(triple: &Triple<'a>, mask: TripleMask) -> Triple<'a> {
let pseudo_subject = if mask.is_set(&TripleMask::SUBJECT) {
&triple.subject.pseudo()
} else {
&triple.subject.clone()
};

pub fn hash_parts(&self, mask: TriplePart) -> Triple {
let hash_subject = if mask.is_set(TriplePart::SUBJECT) {
hash(&self.subject)
} else {
self.subject.clone()
};

let hash_predicate = if mask.is_set(TriplePart::PREDICATE) {
hash(&self.predicate)
} else {
self.predicate.clone()
};

let hash_object = if mask.is_set(TriplePart::OBJECT) {
hash(&self.object)
} else {
self.object.clone()
};

return Triple::new(hash_subject, hash_predicate, hash_object);
let pseudo_object = if mask.is_set(&TripleMask::OBJECT) {
triple.object.pseudo()
} else {
triple.object.clone()
};

return Triple {
subject: *pseudo_subject,
predicate: triple.predicate,
object: pseudo_object,
};
}

// Pseudonymization of objects (Nodes or literals)
impl Pseudonymize for Term<'_> {
fn pseudo(&self) -> Self {
match self {
Term::Literal(val) => Term::Literal(*val),
Term::NamedNode(val) => Term::NamedNode(*val),
Term::BlankNode(val) => Term::BlankNode(*val),
Term::Triple(_) => panic!("RDF-star not supported (triple as object)"),
}
}
}

// instantiate a triple from a ntriple string
pub fn parse_ntriples(triple: &str) -> Triple {
Triple::new(String::from("A"), String::from("B"), String::from("C"))
// Pseudonymization of subjects (always a URI / blank node)
impl Pseudonymize for Subject<'_> {
fn pseudo(&self) -> Self {
match self {
Subject::NamedNode(val) => Subject::NamedNode(*val),
Subject::BlankNode(val) => Subject::BlankNode(*val),
Subject::Triple(_) => panic!("RDF-star not supported (triple as subject)"),
}
}
}

// TODO: implement for blanknodes
// NOTE: Support for RDF-star?
24 changes: 18 additions & 6 deletions src/pass_second.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,23 @@
use rio_api::{model::Triple, parser::TriplesParser};
use rio_turtle::TurtleError;
use std::{
io::{BufRead, BufReader},
path::Path,
};

use crate::{info, io, log::Logger, model::TriplePart};
use crate::{
io,
log::Logger,
model::{pseudonymize_triple, TripleMask},
};

// mask and encode input triple
// NOTE: This will need the type-map to perform masking
fn process_triple(triple: &Triple) -> Result<(), TurtleError> {
let mask = TripleMask::SUBJECT;
println!("{}", pseudonymize_triple(&triple, mask).to_string());
Ok(())
}

pub fn encrypt(log: &Logger, input: &Path, config: &Path, output: &Path, type_map_file: &Path) {
// Construct the buffer either from `stdio` or from an input file.
Expand All @@ -14,11 +28,9 @@ pub fn encrypt(log: &Logger, input: &Path, config: &Path, output: &Path, type_ma
};

let config = io::parse_config(config);

let triples = io::parse_ntriples(buffer);

for triple in triples {
info!(log, "{:?}", triple.hash_parts(TriplePart::SUBJECT));
let mut triples = io::parse_ntriples(buffer);
while !triples.is_end() {
triples.parse_step(&mut |t| process_triple(&t)).unwrap();
}
}
#[cfg(test)]
Expand Down

0 comments on commit cb9b7eb

Please sign in to comment.