kitab

Unnamed repository; edit this file 'description' to name the repository.
Info | Log | Files | Refs | LICENSE

commit d84c216098da4ebfcb1c56642513d3985ae67662
parent e97cf6c27689ae457e28527b9df0cbe4d4ad52e1
Author: lash <dev@holbrook.no>
Date:   Sun, 25 Sep 2022 18:47:39 +0000

Enable multiple digest on biblatex import

Diffstat:
Msrc/biblatex.rs | 66++++++++++++++++++++++++++++--------------------------------------
Msrc/digest.rs | 34++++++++++++++++++++++++++++------
Msrc/error.rs | 12+++++++++++-
Msrc/meta.rs | 21++++++++++++++++-----
Msrc/rdf.rs | 2+-
5 files changed, 84 insertions(+), 51 deletions(-)

diff --git a/src/biblatex.rs b/src/biblatex.rs @@ -28,36 +28,7 @@ fn parse_digest(entry: &Entry) -> RecordDigest { }, }; let note_s = String::from_chunks(note).unwrap(); - let mut digest_val = note_s.split(":"); - - //let mut digest = Vec::new(); - let mut digest: RecordDigest = RecordDigest::Empty; - - match digest_val.next() { - Some(v) => { -// if v == "sha512" { -// let digest_hex = digest_val.next().unwrap(); -// let mut digest_imported = hex::decode(digest_hex).unwrap(); -// digest.append(&mut digest_imported); -// debug!("parsed digest {}", hex::encode(&digest)); -// } - match from_urn(v) { - Ok(r) => { - digest = r; - }, - Err(e) => { - debug!("note for entry {:?} is not a digest url", &entry); - }, - } - }, - None => {}, - }; - -// if digest.len() == 0 { -// digest.resize(64, 0); -// } - - digest + from_urn(note_s.as_str()).unwrap() } /// Read one or more metadata entries from the `bibtex` source. @@ -76,10 +47,15 @@ pub fn read_all(mut r: impl Read, digests: &Vec<RecordDigest>) -> Result<Vec<Met }, Err(e) => { error!("parse error for biblatex"); - return Err(ParseError); + return Err(ParseError::new("Not a biblatex source")); }, }; + if bib.len() > 1 && digests.len() > 0 { + error!("more than one biblatex entry parsed while static digest provided"); + return Err(ParseError::new("more than one biblatex entry parsed while static digest provided")); + } + let mut rr: Vec<MetaData> = vec!(); for e in bib.iter() { @@ -97,6 +73,8 @@ pub fn read_all(mut r: impl Read, digests: &Vec<RecordDigest>) -> Result<Vec<Met }); let mut use_digests: Vec<RecordDigest> = vec!(); + + // use clone instead let digest = parse_digest(&e); match digest { RecordDigest::Empty => { @@ -113,13 +91,6 @@ pub fn read_all(mut r: impl Read, digests: &Vec<RecordDigest>) -> Result<Vec<Met RecordDigest::SwarmHash(r) => { use_digests.push(RecordDigest::SwarmHash(r)); }, - -// RecordDigest::Sha512(r) => { -// use_digests.push(digest); -// }, -// RecordDigest::MD5(r) => { -// use_digests.push(digest); -// }, } for v in digests { @@ -128,6 +99,10 @@ pub fn read_all(mut r: impl Read, digests: &Vec<RecordDigest>) -> Result<Vec<Met let title = e.title().unwrap(); let title_s = String::from_chunks(title).unwrap(); + if use_digests.len() == 0 { + return Err(ParseError::new("no digests found")); + } + for dd in use_digests.into_iter() { let mut m = MetaData::new(title_s.as_str(), authors_s.as_str(), e.entry_type.clone(), dd, None); @@ -160,6 +135,21 @@ mod tests { use env_logger; #[test] + fn test_embedded_digest() { + let biblatex_src = "@article{ + foo, + title={bar}, + author={Guybrush Threepwood}, + note={sha512:f7fbba6e0636f890e56fbbf3283e524c6fa3204ae298382d624741d0dc6638326e282c41be5e4254d8820772c5518a2c5a8c0c7f7eda19594a7eb539453e1ed7}, +} +"; + let digests = vec!(); + let r = read_all(biblatex_src.as_bytes(), &digests).unwrap(); + + } + + + #[test] fn test_multi_digest() { let d_hex = "acbd18db4cc2f85cedef654fccc4a4d8"; let d = digest::RecordDigest::MD5(hex::decode(d_hex).unwrap()); diff --git a/src/digest.rs b/src/digest.rs @@ -41,6 +41,28 @@ impl Clone for RecordDigest { } } +impl RecordDigest { + pub fn fingerprint(&self) -> Vec<u8> { + match self { + RecordDigest::Empty => { + return vec!(); + }, + RecordDigest::Sha512(v) => { + return v.to_vec(); + }, + RecordDigest::Sha256(v) => { + return v.to_vec(); + }, + RecordDigest::MD5(v) => { + return v.to_vec(); + }, + RecordDigest::SwarmHash(v) => { + return v.to_vec(); + }, + } + } +} + /// Create a [RecordDigest::Sha512](RecordDigest::Sha512) instance from the raw digest data. /// @@ -48,7 +70,7 @@ impl Clone for RecordDigest { pub fn from_vec(v: Vec<u8>) -> Result<RecordDigest, ParseError> { let sz = Sha512::output_size(); if v.len() != sz { - return Err(ParseError); + return Err(ParseError::new("invalid digest size")); } Ok(RecordDigest::Sha512(v)) } @@ -71,7 +93,7 @@ pub fn from_urn(urn: &str) -> Result<RecordDigest, ParseError> { vv }, Err(e) => { - return Err(ParseError); + return Err(ParseError::new("invalid sha512 digest")); }, } }, @@ -81,7 +103,7 @@ pub fn from_urn(urn: &str) -> Result<RecordDigest, ParseError> { let sz = Sha256::output_size(); if digest.len() != sz { - return Err(ParseError); + return Err(ParseError::new("invalid sha256 digest")); } RecordDigest::Sha256(digest) @@ -91,7 +113,7 @@ pub fn from_urn(urn: &str) -> Result<RecordDigest, ParseError> { let digest = hex::decode(digest_hex).unwrap(); if digest.len() != 16 { - return Err(ParseError); + return Err(ParseError::new("invalid md5 digest")); } RecordDigest::MD5(digest) @@ -101,7 +123,7 @@ pub fn from_urn(urn: &str) -> Result<RecordDigest, ParseError> { let digest = hex::decode(digest_hex).unwrap(); if digest.len() != 32 { - return Err(ParseError); + return Err(ParseError::new("invalid bzz digest")); } RecordDigest::SwarmHash(digest) @@ -110,7 +132,7 @@ pub fn from_urn(urn: &str) -> Result<RecordDigest, ParseError> { RecordDigest::Empty }, Some(_) => { - return Err(ParseError); + return Err(ParseError::new("unknown digest type")); }, None => { RecordDigest::Empty diff --git a/src/error.rs b/src/error.rs @@ -1,3 +1,13 @@ /// Used for any parsing error for any supported format. #[derive(Debug)] -pub struct ParseError; +pub struct ParseError { + pub detail: String, +} + +impl ParseError { + pub fn new(s: &str) -> ParseError { + ParseError{ + detail: String::from(s), + } + } +} diff --git a/src/meta.rs b/src/meta.rs @@ -210,7 +210,9 @@ impl MetaData { } /// Returns the digest value of the media as a hex-encoded string. - pub fn fingerprint(&self) -> String { + /// + /// TODO: implememt in fmt for digest instead + pub fn urn(&self) -> String { match &self.digest { digest::RecordDigest::Empty => { return String::new(); @@ -230,6 +232,13 @@ impl MetaData { } } + + /// + pub fn fingerprint(&self) -> String { + let digest_fingerprint = self.digest.fingerprint(); + return hex::encode(digest_fingerprint); + } + /// Instantiate metadata from the extended attributes of the file in `filepath`. pub fn from_xattr(filepath: &path::Path) -> Result<MetaData, ParseError> { @@ -253,7 +262,7 @@ impl MetaData { v }, Err(e) => { - return Err(ParseError{}); + return Err(ParseError::new("title missing")); } }; match title_src { @@ -285,7 +294,7 @@ impl MetaData { let mut metadata = MetaData::new(title.as_str(), author.as_str(), typ, digest::RecordDigest::Sha512(digest), Some(filename)); if !metadata.validate() { - return Err(ParseError{}); + return Err(ParseError::new("invalid input")); } match xattr::get(filepath, "user.dcterms:subject") { @@ -509,7 +518,8 @@ mod tests { let meta = MetaData::from_xattr(s).unwrap(); assert_eq!(meta.dc.title, "Bitcoin: A Peer-to-Peer Electronic Cash System"); assert_eq!(meta.dc.author, "Satoshi Nakamoto"); - assert_eq!(meta.fingerprint(), String::from("sha512:2ac531ee521cf93f8419c2018f770fbb42c65396178e079a416e7038d3f9ab9fc2c35c4d838bc8b5dd68f4c13759fe9cdf90a46528412fefe1294cb26beabf4e")); + assert_eq!(meta.urn(), String::from("sha512:2ac531ee521cf93f8419c2018f770fbb42c65396178e079a416e7038d3f9ab9fc2c35c4d838bc8b5dd68f4c13759fe9cdf90a46528412fefe1294cb26beabf4e")); + assert_eq!(meta.fingerprint(), String::from("2ac531ee521cf93f8419c2018f770fbb42c65396178e079a416e7038d3f9ab9fc2c35c4d838bc8b5dd68f4c13759fe9cdf90a46528412fefe1294cb26beabf4e")); } #[test] @@ -531,7 +541,8 @@ mod tests { let m_check = MetaData::from_xattr(fp).unwrap(); assert_eq!(m_check.title(), "foo"); assert_eq!(m_check.author(), "bar"); - assert_eq!(m_check.fingerprint(), String::from("sha512:") + digest_hex); + assert_eq!(m_check.fingerprint(), digest_hex); + assert_eq!(m_check.urn(), String::from("sha512:") + digest_hex); assert_eq!(m_check.typ(), EntryType::Article); assert_eq!(m_check.subject().unwrap(), "baz"); assert_eq!(m_check.mime().unwrap(), "foo/bar"); diff --git a/src/rdf.rs b/src/rdf.rs @@ -233,7 +233,7 @@ pub fn read_all(r: impl Read) -> Result<Vec<MetaData>, ParseError> { }); // TODO: should check validity of all records if rr[0].fingerprint() == "" { - return Err(ParseError); + return Err(ParseError::new("empty fingerprint")); } Ok(rr) }