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.prepare(&crate::config::SchemaSettings::default()).map_err(|_| Error::InvalidInput {
60            field: "storage schema",
61            reason: "invalid finite schema graph",
62        })?;
63        Ok(Self { key, graph })
64    }
65
66    pub fn graph(&self) -> &Schema {
67        &self.graph
68    }
69
70    pub fn graph_owner(&self) -> Arc<Schema> {
71        Arc::clone(&self.graph)
72    }
73}
74impl MemorySize for SchemaInput {
75    fn memory_size(&self) -> usize {
76        std::mem::size_of::<Self>() + self.key.memory_size() - std::mem::size_of::<SchemaKey>()
77            + self.graph.memory_size()
78            + 2 * std::mem::size_of::<usize>()
79    }
80}
81impl MemorySize for SchemaInfo {
82    fn memory_size(&self) -> usize {
83        std::mem::size_of::<Self>() + self.position.memory_size() - std::mem::size_of::<StorageCursor>() + self.schema.memory_size()
84            - std::mem::size_of::<SchemaInput>()
85    }
86}
87
88/* === Public Functions === */
89
90/* === Private Functions === */
91
92/* === Tests === */
93
94#[cfg(test)]
95mod tests {
96    use super::*;
97    use crate::{Identifier, Message};
98
99    #[test]
100    fn graph_owner_retained() {
101        let mut definitions = Vec::with_capacity(8);
102        definitions.push(Vec::with_capacity(16));
103        let pointer = definitions.as_ptr();
104        let graph = Schema { root: 0, definitions };
105        let key = SchemaKey {
106            id: Identifier::new("owned.schema").unwrap(),
107            version: std::num::NonZeroU32::MIN,
108            payload_encoding: crate::model::storage::PayloadEncoding::PostcardV1,
109        };
110        let input = SchemaInput::new(key, graph).unwrap();
111        assert_eq!(input.graph().definitions.as_ptr(), pointer);
112        assert_eq!(input.graph().definitions.capacity(), 8);
113        let retained = input.graph_owner();
114        let duplicate = input.clone();
115        assert!(Arc::ptr_eq(&retained, &duplicate.graph_owner()));
116        let encoded = input.encode();
117        let decoded = SchemaInput::decode(&encoded).unwrap();
118        assert_eq!(decoded, input);
119        assert!(input.memory_size() >= input.graph().memory_size());
120    }
121}