ostree_ext/
objectsource.rs

1//! Metadata about the source of an object: a component or package.
2//!
3//! This is used to help split up containers into distinct layers.
4
5use indexmap::IndexMap;
6use std::borrow::Borrow;
7use std::collections::HashSet;
8use std::hash::Hash;
9use std::rc::Rc;
10
11use serde::{Deserialize, Serialize, Serializer};
12
13mod rcstr_serialize {
14    use serde::Deserializer;
15
16    use super::*;
17
18    pub(crate) fn serialize<S>(v: &Rc<str>, serializer: S) -> Result<S::Ok, S::Error>
19    where
20        S: Serializer,
21    {
22        serializer.serialize_str(v)
23    }
24
25    pub(crate) fn deserialize<'de, D>(deserializer: D) -> Result<Rc<str>, D::Error>
26    where
27        D: Deserializer<'de>,
28    {
29        let v = String::deserialize(deserializer)?;
30        Ok(Rc::from(v.into_boxed_str()))
31    }
32}
33
34/// Identifier for content (e.g. package/layer).  Not necessarily human readable.
35/// For example in RPMs, this may be a full "NEVRA" i.e. name-epoch:version-release.architecture e.g. kernel-6.2-2.fc38.aarch64
36/// But that's not strictly required as this string should only live in memory and not be persisted.
37pub type ContentID = Rc<str>;
38
39/// Metadata about a component/package.
40#[derive(Debug, Eq, Deserialize, Serialize)]
41pub struct ObjectSourceMeta {
42    /// Unique identifier, does not need to be human readable, but can be.
43    #[serde(with = "rcstr_serialize")]
44    pub identifier: ContentID,
45    /// Just the name of the package (no version), needs to be human readable.
46    #[serde(with = "rcstr_serialize")]
47    pub name: Rc<str>,
48    /// Identifier for the *source* of this content; for example, if multiple binary
49    /// packages derive from a single git repository or source package.
50    #[serde(with = "rcstr_serialize")]
51    pub srcid: Rc<str>,
52    /// Unitless, relative offset of last change time.
53    /// One suggested way to generate this number is to have it be in units of hours or days
54    /// since the earliest changed item.
55    pub change_time_offset: u32,
56    /// Change frequency
57    pub change_frequency: u32,
58}
59
60impl PartialEq for ObjectSourceMeta {
61    fn eq(&self, other: &Self) -> bool {
62        *self.identifier == *other.identifier
63    }
64}
65
66impl Hash for ObjectSourceMeta {
67    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
68        self.identifier.hash(state);
69    }
70}
71
72impl Borrow<str> for ObjectSourceMeta {
73    fn borrow(&self) -> &str {
74        &self.identifier
75    }
76}
77
78/// Maps from e.g. "bash" or "kernel" to metadata about that content
79pub type ObjectMetaSet = HashSet<ObjectSourceMeta>;
80
81/// Maps from an ostree content object digest to the `ContentSet` key.
82pub type ObjectMetaMap = IndexMap<String, ContentID>;
83
84/// Grouping of metadata about an object.
85#[derive(Debug, Default)]
86pub struct ObjectMeta {
87    /// The set of object sources with their metadata.
88    pub set: ObjectMetaSet,
89    /// Mapping from content object to source.
90    pub map: ObjectMetaMap,
91}