infinitree/tree/
commit.rs

1use crate::Id;
2use serde::{Deserialize, Serialize};
3use serde_with::serde_as;
4use std::{sync::Arc, time::SystemTime};
5
6/// The list of commits already recorded
7pub type CommitList<CustomData> = Vec<Arc<Commit<CustomData>>>;
8
9/// A representation of a generation within the tree
10pub type CommitId = Id;
11
12/// Identifies a cryptographically secured set of transactions on the tree.
13#[serde_as]
14#[derive(Serialize, Deserialize, Debug)]
15pub struct Commit<CustomData>
16where
17    CustomData: Serialize,
18{
19    /// Cryptographic hash of the commit contents
20    pub id: CommitId,
21
22    /// Metadata associated with the commit
23    pub metadata: CommitMetadata<CustomData>,
24}
25
26/// Hashed metadata of a [`Commit`] that are included in its
27/// [`id`][Commit::id]
28#[serde_as]
29#[derive(Serialize, Deserialize, Debug)]
30pub struct CommitMetadata<CustomData>
31where
32    CustomData: Serialize,
33{
34    /// Previous commit in the chain
35    pub previous: Option<CommitId>,
36
37    /// Any additional stringy message, just like in Git
38    pub message: Option<String>,
39
40    /// Time the commit was made
41    #[serde_as(as = "serde_with::TimestampSecondsWithFrac<f64>")]
42    pub time: SystemTime,
43
44    /// Any machine-readable data you may need to store
45    pub custom_data: CustomData,
46}
47
48impl<CustomData: Serialize + Default> Default for CommitMetadata<CustomData> {
49    fn default() -> Self {
50        Self {
51            time: SystemTime::now(),
52            previous: None,
53            message: None,
54            custom_data: CustomData::default(),
55        }
56    }
57}
58
59/// Enum to navigate the versions that are available in an Infinitree
60pub enum CommitFilter {
61    /// On querying, all versions will be crawled. This is the
62    /// default.
63    All,
64
65    /// Only a single generation will be looked at during querying.
66    Single(CommitId),
67
68    /// All generations up to and including the given one will be queried.
69    UpTo(CommitId),
70
71    /// Only use generations between the two given versions.
72    /// The first parameter **must** be earlier generation than the
73    /// second.
74    Range(CommitId, CommitId),
75}
76
77impl Default for CommitFilter {
78    fn default() -> Self {
79        Self::All
80    }
81}
82
83/// A commit message. Mostly equivalent to Option<String>.
84///
85/// The main reason for a separate wrapper type is being able to use
86/// versatile `From<T>` implementations that in return make the
87/// `Infinitree` API nicer to use.
88pub enum Message {
89    /// No commit message.
90    Empty,
91    /// Use the `String` parameter as commit message
92    Some(String),
93}
94
95impl From<&str> for Message {
96    fn from(from: &str) -> Self {
97        Self::Some(from.to_string())
98    }
99}
100
101impl From<Option<String>> for Message {
102    fn from(from: Option<String>) -> Self {
103        match from {
104            Some(s) => Self::Some(s),
105            None => Self::Empty,
106        }
107    }
108}
109
110impl From<String> for Message {
111    fn from(from: String) -> Self {
112        Self::Some(from)
113    }
114}
115
116impl From<Message> for Option<String> {
117    fn from(from: Message) -> Option<String> {
118        match from {
119            Message::Empty => None,
120            Message::Some(s) => Some(s),
121        }
122    }
123}