biblatex.rs (4598B)
1 use std::io::{ 2 Read, 3 }; 4 use std::str; 5 6 use log::{ 7 debug, 8 error, 9 }; 10 use biblatex::{ 11 Bibliography, 12 Type, 13 Entry as Entry, 14 }; 15 16 use crate::meta::MetaData; 17 use crate::error::ParseError; 18 use crate::digest::RecordDigest; 19 use crate::digest::from_urn; 20 21 fn parse_digest(entry: &Entry) -> RecordDigest { 22 let note = match entry.get("note") { 23 Some(v) => { 24 v 25 }, 26 None => { 27 return RecordDigest::Empty; 28 }, 29 }; 30 let note_s = String::from_chunks(note).unwrap(); 31 from_urn(note_s.as_str()).unwrap() 32 } 33 34 /// Read one or more metadata entries from the `bibtex` source. 35 /// 36 /// Will return `ParseError` if any of the records are invalid. 37 /// 38 /// # Arguments 39 /// 40 /// * `r` - reader implementation providing the source. 41 pub fn read_all(mut r: impl Read, digests: &Vec<RecordDigest>) -> Result<Vec<MetaData>, ParseError> { 42 let mut s = String::new(); 43 let c = r.read_to_string(&mut s); 44 let bib = match Bibliography::parse(&s) { 45 Ok(v) => { 46 v 47 }, 48 Err(e) => { 49 error!("parse error for biblatex"); 50 return Err(ParseError::new("Not a biblatex source")); 51 }, 52 }; 53 54 if bib.len() > 1 && digests.len() > 0 { 55 error!("more than one biblatex entry parsed while static digest provided"); 56 return Err(ParseError::new("more than one biblatex entry parsed while static digest provided")); 57 } 58 59 let mut rr: Vec<MetaData> = vec!(); 60 61 for e in bib.iter() { 62 let authors = e.author() 63 .unwrap() 64 .into_iter() 65 .map(|v| { 66 format!("{} {}", v.given_name, v.name) 67 }); 68 let authors_s = authors.fold(String::new(), |x, y| { 69 if x.len() == 0 { 70 return y 71 } 72 format!("{}, {}", x, y) 73 }); 74 75 let mut use_digests: Vec<RecordDigest> = vec!(); 76 77 // use clone instead 78 let digest = parse_digest(&e); 79 match digest { 80 RecordDigest::Sha512(r) => { 81 use_digests.push(RecordDigest::Sha512(r)); 82 }, 83 RecordDigest::Sha256(r) => { 84 use_digests.push(RecordDigest::Sha256(r)); 85 }, 86 RecordDigest::MD5(r) => { 87 use_digests.push(RecordDigest::MD5(r)); 88 }, 89 RecordDigest::SwarmHash(r) => { 90 use_digests.push(RecordDigest::SwarmHash(r)); 91 }, 92 _ => { 93 }, 94 } 95 96 for v in digests { 97 use_digests.push(v.clone()); 98 } 99 let title = e.title().unwrap(); 100 let title_s = String::from_chunks(title).unwrap(); 101 102 if use_digests.len() == 0 { 103 return Err(ParseError::new("no digests found")); 104 } 105 106 for dd in use_digests.into_iter() { 107 let mut m = MetaData::new(title_s.as_str(), authors_s.as_str(), e.entry_type.clone(), dd, None); 108 109 match e.keywords() { 110 Ok(v) => { 111 let s = String::from_chunks(v).unwrap(); 112 m.set_subject(s.as_str()); 113 }, 114 _ => {}, 115 }; 116 117 match e.language() { 118 Ok(v) => { 119 m.set_language(v.as_str()); 120 }, 121 _ => {}, 122 } 123 124 debug!("read metadata {:?}", &m); 125 rr.push(m); 126 } 127 } 128 Ok(rr) 129 } 130 131 #[cfg(test)] 132 mod tests { 133 use super::read_all; 134 use crate::digest; 135 use env_logger; 136 137 #[test] 138 fn test_embedded_digest() { 139 let biblatex_src = "@article{ 140 foo, 141 title={bar}, 142 author={Guybrush Threepwood}, 143 note={sha512:f7fbba6e0636f890e56fbbf3283e524c6fa3204ae298382d624741d0dc6638326e282c41be5e4254d8820772c5518a2c5a8c0c7f7eda19594a7eb539453e1ed7}, 144 } 145 "; 146 let digests = vec!(); 147 let r = read_all(biblatex_src.as_bytes(), &digests).unwrap(); 148 149 } 150 151 152 #[test] 153 fn test_multi_digest() { 154 let d_hex = "acbd18db4cc2f85cedef654fccc4a4d8"; 155 let d = digest::RecordDigest::MD5(hex::decode(d_hex).unwrap()); 156 let d_sha_hex = "f7fbba6e0636f890e56fbbf3283e524c6fa3204ae298382d624741d0dc6638326e282c41be5e4254d8820772c5518a2c5a8c0c7f7eda19594a7eb539453e1ed7"; 157 let d_sha = digest::from_vec(hex::decode(d_sha_hex).unwrap()).unwrap(); 158 159 let biblatex_src = "@article{ 160 foo, 161 title={bar}, 162 author={Guybrush Threepwood}, 163 } 164 "; 165 let digests = vec!(d, d_sha); 166 let r = read_all(biblatex_src.as_bytes(), &digests).unwrap(); 167 168 assert_eq!(r.len(), 2); 169 } 170 }