1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
//! Representation of the actual data.

use semver::Version;

/// A Model is a representation of data.
///
/// A model (as you probably guessed) models data. Specifically, a Model implementation describes:
///     1. Describes what the data will look like (structure, types, etcetera)
///     2. The model's name
///     3. The model's version
///
/// Actual instances of implementations will hold the data.
///
/// ## Describing the data
///
/// Describing the data structure is easy: add fields to the struct implementing the model.
pub trait Model {
    /// The name of the model.
    /// Each type of model has a name (not to be confused with a model instance's key), this is the
    /// used by the PersistenceEngine to determine which Persister to use when storing or retrieving
    /// the model.
    ///
    /// While not required, it is recommended that the name of the model be the same as the name of
    /// the implementing type, but in kebab-case instead of PascalCase.
    fn model_name() -> &'static str;

    /// Each model implementation has a version. When the structure of that model changes, the
    /// version also needs to change. As of right now, the model implementation must handle
    /// converting from an older version to a newer version when deserializing from bytes.
    ///
    /// You may notice that this is defined on a `Self` level and not a `self` level. This is
    /// because all loaded models of a single type should have the same version, and that version
    /// should not change without changes in the code as well.
    fn model_version() -> &'static Version;

    /// Gets the key for the model instance. As you can probably guess, the key uniquely identifies
    /// a model instance (as opposed to the `model_name` which uniquely identifies a model type).
    fn get_key(&self) -> &str;
}

/// A representation of a stored [model](Model). While every [model](Model) type has it's own
/// version when loaded, the same cannot be said before they're loaded, or while they're in the
/// process of being loaded. This acts as representation of that.
#[derive(Debug)]
pub struct StoredModel<M: Model> {
    pub version: Version,
    pub model: M,
}

impl<M: Model> From<(Version, M)> for StoredModel<M> {
    fn from((version, model): (Version, M)) -> Self {
        Self { version, model }
    }
}