on 2ffbe08 help sign in
bat/src/assets_metadata.rs
81 lines 2.8 kB history raw
1use std::fs::File;
2use std::path::Path;
3use std::time::SystemTime;
5use semver::Version;
6use serde::{Deserialize, Serialize};
8use crate::error::*;
10#[derive(Debug, PartialEq, Default, Serialize, Deserialize)]
11pub struct AssetsMetadata {
12 bat_version: Option<String>,
13 creation_time: Option<SystemTime>,
16const FILENAME: &str = "metadata.yaml";
18impl AssetsMetadata {
19 pub(crate) fn new(current_version: &str) -> AssetsMetadata {
20 AssetsMetadata {
21 bat_version: Some(current_version.to_owned()),
22 creation_time: Some(SystemTime::now()),
23 }
24 }
26 pub(crate) fn save_to_folder(&self, path: &Path) -> Result<()> {
27 let file = File::create(path.join(FILENAME))?;
28 serde_yaml::to_writer(file, self)?;
30 Ok(())
31 }
33 fn try_load_from_folder(path: &Path) -> Result<Self> {
34 let file = File::open(path.join(FILENAME))?;
35 Ok(serde_yaml::from_reader(file)?)
36 }
38 /// Load metadata about the stored cache file from the given folder.
39 ///
40 /// There are several possibilities:
41 /// - We find a metadata.yaml file and are able to parse it
42 /// => return the contained information
43 /// - We find a metadata.yaml file and but are not able to parse it
44 /// => return a SerdeYamlError
45 /// - We do not find a metadata.yaml file but a syntaxes.bin or themes.bin file
46 /// => assume that these were created by an old version of bat and return
47 /// AssetsMetadata::default() without version information
48 /// - We do not find a metadata.yaml file and no cached assets
49 /// => no user provided assets are available, return None
50 pub fn load_from_folder(path: &Path) -> Result<Option<Self>> {
51 match Self::try_load_from_folder(path) {
52 Ok(metadata) => Ok(Some(metadata)),
53 Err(e) => match e.kind() {
54 ErrorKind::SerdeYamlError(_) => Err(e),
55 _ => {
56 if path.join("syntaxes.bin").exists() || path.join("themes.bin").exists() {
57 Ok(Some(Self::default()))
58 } else {
59 Ok(None)
60 }
61 }
62 },
63 }
64 }
66 pub fn is_compatible_with(&self, current_version: &str) -> bool {
67 let current_version =
68 Version::parse(current_version).expect("bat follows semantic versioning");
69 let stored_version = self
70 .bat_version
71 .as_ref()
72 .and_then(|ver| Version::parse(ver).ok());
74 if let Some(stored_version) = stored_version {
75 current_version.major == stored_version.major
76 && current_version.minor == stored_version.minor
77 } else {
78 false
79 }
80 }