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:
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)
}