scancode_rust/askalono/store/
cache.rs1use std::{io::copy, io::prelude::*};
5
6use anyhow::Error;
7use log::info;
8use rmp_serde::Serializer;
9use serde::Serialize;
10
11use crate::askalono::store::base::Store;
12
13const CACHE_VERSION: &[u8] = b"askalono-04";
14
15impl Store {
16 pub fn from_cache<R>(mut readable: R) -> Result<Store, Error>
24 where
25 R: Read + Sized,
26 {
27 let mut header = [0u8; 11];
28 readable.read_exact(&mut header)?;
29
30 if header != CACHE_VERSION {
31 anyhow::bail!(
32 "cache version mismatch; expected '{}', found '{}'",
33 String::from_utf8_lossy(CACHE_VERSION),
34 String::from_utf8_lossy(&header)
35 );
36 }
37
38 #[cfg(not(feature = "gzip"))]
39 let dec = zstd::Decoder::new(readable)?;
40 #[cfg(feature = "gzip")]
41 let dec = flate2::read::GzDecoder::new(readable);
42
43 let store = rmp_serde::decode::from_read(dec)?;
44 Ok(store)
45 }
46
47 pub fn to_cache<W>(&self, mut writable: W) -> Result<(), Error>
52 where
53 W: Write + Sized,
54 {
55 let buf = {
56 let mut buf = Vec::with_capacity(4 * 1024 * 1024);
58 let mut serializer = Serializer::new(&mut buf);
59 self.serialize(&mut serializer)?;
60 buf
61 };
62
63 info!("Pre-compressed output is {} bytes", buf.len());
64
65 writable.write_all(CACHE_VERSION)?;
66
67 #[cfg(not(feature = "gzip"))]
68 let mut enc = zstd::Encoder::new(writable, 21)?;
69 #[cfg(feature = "gzip")]
70 let mut enc = flate2::write::GzEncoder::new(writable, flate2::Compression::default());
71
72 copy(&mut buf.as_slice(), &mut enc)?;
73 enc.finish()?;
74
75 Ok(())
76 }
77}