kitab

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

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 }