Skip to main content

systemprompt_models/services/
includable.rs

1//! [`IncludableString`] — a string field that can either carry inline
2//! content or a `!include <path>` reference resolved at load time.
3
4use serde::{Deserialize, Deserializer, Serialize};
5
6#[derive(Debug, Clone, Serialize)]
7#[serde(untagged)]
8pub enum IncludableString {
9    Inline(String),
10    Include { path: String },
11}
12
13impl<'de> Deserialize<'de> for IncludableString {
14    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
15    where
16        D: Deserializer<'de>,
17    {
18        let s = String::deserialize(deserializer)?;
19        Ok(s.strip_prefix("!include ").map_or_else(
20            || Self::Inline(s.clone()),
21            |path| Self::Include {
22                path: path.trim().to_string(),
23            },
24        ))
25    }
26}
27
28impl IncludableString {
29    #[must_use]
30    pub const fn is_include(&self) -> bool {
31        matches!(self, Self::Include { .. })
32    }
33
34    #[must_use]
35    pub fn as_inline(&self) -> Option<&str> {
36        match self {
37            Self::Inline(s) => Some(s),
38            Self::Include { .. } => None,
39        }
40    }
41}
42
43impl Default for IncludableString {
44    fn default() -> Self {
45        Self::Inline(String::new())
46    }
47}