Skip to main content

harmos_domain/model/storage/
schema_input.rs

1/* ***
2 *
3 * Harmos
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * ***
8 */
9
10/* === Modules === */
11
12/* === Re-Exports === */
13
14/* === Imports === */
15
16// Standard Library Imports
17use std::sync::Arc;
18
19// Third Party Imports
20
21// Local Imports
22use crate::model::storage::codec::{Nested, Shared, product};
23use crate::model::storage::{SchemaKey, StorageCursor};
24use crate::schema::graph::Schema;
25use crate::{Error, MemorySize, Result};
26
27/* === Constants === */
28
29/* === Macros === */
30
31product!(SchemaInput { key: Nested<SchemaKey> => 1, graph: Shared<Schema> => 2 });
32product!(SchemaInfo { position: Nested<StorageCursor> => 1, schema: Nested<SchemaInput> => 2 });
33
34/* === Type Aliases === */
35
36/* === Structs === */
37
38#[derive(Clone, Debug, PartialEq, Eq)]
39pub struct SchemaInput {
40    pub key: SchemaKey,
41    graph: Arc<Schema>,
42}
43
44#[derive(Clone, Debug, PartialEq, Eq)]
45pub struct SchemaInfo {
46    pub position: StorageCursor,
47    pub schema: SchemaInput,
48}
49
50/* === Enums === */
51
52/* === Traits === */
53
54/* === Implementations === */
55
56impl SchemaInput {
57    pub fn new(key: SchemaKey, graph: impl Into<Arc<Schema>>) -> Result<Self> {
58        let graph = graph.into();
59        graph
60            .prepare(&crate::config::SchemaSettings::default())
61            .map_err(|_| Error::InvalidInput { field: "storage schema", reason: "invalid finite schema graph" })?;
62        Ok(Self { key, graph })
63    }
64
65    pub fn graph(&self) -> &Schema {
66        &self.graph
67    }
68
69    pub fn graph_owner(&self) -> Arc<Schema> {
70        Arc::clone(&self.graph)
71    }
72}
73impl MemorySize for SchemaInput {
74    fn memory_size(&self) -> usize {
75        std::mem::size_of::<Self>() + self.key.memory_size() - std::mem::size_of::<SchemaKey>()
76            + self.graph.memory_size()
77            + 2 * std::mem::size_of::<usize>()
78    }
79}
80impl MemorySize for SchemaInfo {
81    fn memory_size(&self) -> usize {
82        std::mem::size_of::<Self>() + self.position.memory_size() - std::mem::size_of::<StorageCursor>() + self.schema.memory_size()
83            - std::mem::size_of::<SchemaInput>()
84    }
85}
86
87/* === Public Functions === */
88
89/* === Private Functions === */
90
91/* === Tests === */
92
93#[cfg(test)]
94mod tests {
95    use super::*;
96    use crate::{Identifier, Message};
97
98    #[test]
99    fn graph_owner_retained() {
100        let mut definitions = Vec::with_capacity(8);
101        definitions.push(Vec::with_capacity(16));
102        let pointer = definitions.as_ptr();
103        let graph = Schema { root: 0, definitions };
104        let key = SchemaKey {
105            id: Identifier::new("owned.schema").unwrap(),
106            version: std::num::NonZeroU32::MIN,
107            payload_encoding: crate::model::storage::PayloadEncoding::PostcardV1,
108        };
109        let input = SchemaInput::new(key, graph).unwrap();
110        assert_eq!(input.graph().definitions.as_ptr(), pointer);
111        assert_eq!(input.graph().definitions.capacity(), 8);
112        let retained = input.graph_owner();
113        let duplicate = input.clone();
114        assert!(Arc::ptr_eq(&retained, &duplicate.graph_owner()));
115        let encoded = input.encode_to_vec();
116        let decoded = SchemaInput::decode(&encoded).unwrap();
117        assert_eq!(decoded, input);
118        assert!(input.memory_size() >= input.graph().memory_size());
119    }
120}