Skip to main content

context_engine/
provided.rs

1use alloc::string::String;
2use alloc::vec::Vec;
3use core::fmt;
4
5/// Request-scoped context handle. Manages state per DSL definition.
6pub trait Context {
7    /// Returns value from instance cache → _set, triggers _get on miss.
8    fn get(&mut self, key: &str) -> Result<Option<Tree>, ContextError>;
9
10    /// Writes value to _set. Returns Ok(false) if no _set is configured.
11    fn set(&mut self, key: &str, value: Tree) -> Result<bool, ContextError>;
12
13    /// Removes value from _set.
14    fn delete(&mut self, key: &str) -> Result<bool, ContextError>;
15
16    /// Checks existence in cache or _set. Does not trigger _get.
17    fn exists(&mut self, key: &str) -> Result<bool, ContextError>;
18}
19
20/// The value type used throughout context-engine's public API.
21#[derive(Debug, PartialEq, Clone)]
22pub enum Tree {
23    Scalar(Vec<u8>),
24    Sequence(Vec<Tree>),
25    Mapping(Vec<(Vec<u8>, Tree)>),
26    Null,
27}
28
29// ── Errors ────────────────────────────────────────────────────────────────────
30
31/// DSL parse/compile/file errors returned by `Dsl::compile` and `Dsl::write`.
32#[derive(Debug, PartialEq)]
33pub enum DslError {
34    FileNotFound(String),
35    AmbiguousFile(String),
36    ParseError(String),
37    /// A compile-time limit was exceeded (path_id, word_id, store_id, or data size).
38    LimitExceeded(String),
39}
40
41impl fmt::Display for DslError {
42    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
43        match self {
44            DslError::FileNotFound(msg)   => write!(f, "FileNotFound: {}", msg),
45            DslError::AmbiguousFile(msg)  => write!(f, "AmbiguousFile: {}", msg),
46            DslError::ParseError(msg)     => write!(f, "ParseError: {}", msg),
47            DslError::LimitExceeded(msg)  => write!(f, "LimitExceeded: {}", msg),
48        }
49    }
50}
51
52/// Errors from `_get` store resolution during `Context::get`.
53#[derive(Debug, PartialEq)]
54pub enum LoadError {
55    /// Stores::store_for() returned None for the given store_id.
56    ClientNotFound(String),
57    /// A required config key is missing in the manifest.
58    ConfigMissing(String),
59    /// The store call succeeded but returned no data.
60    NotFound(String),
61    /// Parse error from store response.
62    ParseError(String),
63}
64
65impl fmt::Display for LoadError {
66    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
67        match self {
68            LoadError::ClientNotFound(msg) => write!(f, "ClientNotFound: {}", msg),
69            LoadError::ConfigMissing(msg)  => write!(f, "ConfigMissing: {}", msg),
70            LoadError::NotFound(msg)       => write!(f, "NotFound: {}", msg),
71            LoadError::ParseError(msg)     => write!(f, "ParseError: {}", msg),
72        }
73    }
74}
75
76/// Errors from `_set` store operations during `Context::set` / `Context::delete`.
77#[derive(Debug, PartialEq)]
78pub enum StoreError {
79    /// Stores::store_for() returned None for the given store_id.
80    ClientNotFound(String),
81    /// A required config key is missing in the manifest.
82    ConfigMissing(String),
83    /// Serialize error.
84    SerializeError(String),
85}
86
87impl fmt::Display for StoreError {
88    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
89        match self {
90            StoreError::ClientNotFound(msg) => write!(f, "ClientNotFound: {}", msg),
91            StoreError::ConfigMissing(msg)  => write!(f, "ConfigMissing: {}", msg),
92            StoreError::SerializeError(msg) => write!(f, "SerializeError: {}", msg),
93        }
94    }
95}
96
97/// Top-level errors returned by all `Context` methods.
98#[derive(Debug, PartialEq)]
99pub enum ContextError {
100    ParseFailed(String),
101    KeyNotFound(String),
102    RecursionLimitExceeded,
103    StoreFailed(StoreError),
104    LoadFailed(LoadError),
105}
106
107impl fmt::Display for ContextError {
108    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
109        match self {
110            ContextError::ParseFailed(msg)       => write!(f, "ParseFailed: {}", msg),
111            ContextError::KeyNotFound(msg)       => write!(f, "KeyNotFound: {}", msg),
112            ContextError::RecursionLimitExceeded => write!(f, "RecursionLimitExceeded"),
113            ContextError::StoreFailed(e)         => write!(f, "StoreFailed: {}", e),
114            ContextError::LoadFailed(e)          => write!(f, "LoadFailed: {}", e),
115        }
116    }
117}