Skip to main content

zenith_core/ast/
asset.rs

1//! Asset block and asset declaration AST types.
2
3use std::collections::BTreeMap;
4
5use super::Span;
6use super::node::UnknownProperty;
7
8/// The kind of an asset — determines how bytes are interpreted by consumers.
9///
10/// Mirrors `TokenType`: unknown kind strings are preserved as
11/// `AssetKind::Unknown(String)` for forward-compat. Parse is infallible;
12/// validation emits `asset.invalid_kind` for unrecognized variants.
13#[derive(Debug, Clone, PartialEq, Eq)]
14pub enum AssetKind {
15    /// A raster image (PNG, JPEG, …).
16    Image,
17    /// An SVG vector graphic.
18    Svg,
19    /// A font file (TTF, OTF, WOFF2, …).
20    Font,
21    /// An unrecognized asset kind (forward-compat; version-relative).
22    Unknown(String),
23}
24
25impl AssetKind {
26    /// Parse the asset kind from the `kind` property string. Infallible: an
27    /// unrecognized kind is preserved as `AssetKind::Unknown` (forward-compat).
28    pub fn from_kind_str(s: &str) -> Self {
29        match s {
30            "image" => Self::Image,
31            "svg" => Self::Svg,
32            "font" => Self::Font,
33            other => Self::Unknown(other.to_owned()),
34        }
35    }
36
37    /// Return the canonical string representation of a known kind.
38    ///
39    /// For `Unknown`, returns the stored string slice.
40    pub fn kind_str(&self) -> &str {
41        match self {
42            Self::Image => "image",
43            Self::Svg => "svg",
44            Self::Font => "font",
45            Self::Unknown(s) => s.as_str(),
46        }
47    }
48}
49
50/// A single asset declaration within an `assets` block.
51#[derive(Debug, Clone, PartialEq)]
52pub struct AssetDecl {
53    /// Globally unique asset ID (e.g. `"asset.logo"`).
54    pub id: String,
55    /// The asset kind — required.
56    pub kind: AssetKind,
57    /// Relative path to the asset file — required.
58    pub src: String,
59    /// Optional SHA-256 hex digest for content integrity.
60    pub sha256: Option<String>,
61    /// The prompt text used to generate this asset, if AI-generated.
62    pub ai_prompt: Option<String>,
63    /// The model identifier used to generate this asset (e.g. `"dall-e-3"`).
64    pub ai_model: Option<String>,
65    /// The provider that hosted the generation model (e.g. `"openai"`).
66    pub ai_provider: Option<String>,
67    /// The random seed passed to the generation model, for reproducibility.
68    pub ai_seed: Option<i64>,
69    /// The date on which this asset was generated (free-form string).
70    pub ai_generation_date: Option<String>,
71    /// The license under which the generated asset may be used.
72    pub ai_license: Option<String>,
73    /// Rights information for the source material used during generation.
74    pub ai_source_rights: Option<String>,
75    /// Safety review status of the generated asset.
76    pub ai_safety_status: Option<String>,
77    /// Policy governing reuse of this generated asset.
78    pub ai_reuse_policy: Option<String>,
79    /// Source declaration span, when available.
80    pub source_span: Option<Span>,
81    /// Forward-compat unknown properties captured during parse.
82    pub unknown_props: BTreeMap<String, UnknownProperty>,
83}
84
85/// The top-level `assets` block.
86///
87/// Absent from the document → `AssetBlock::default()` (empty, no error).
88#[derive(Debug, Clone, PartialEq, Default)]
89pub struct AssetBlock {
90    /// The ordered list of asset declarations.
91    pub assets: Vec<AssetDecl>,
92    /// Source span of the `assets { … }` block, when available.
93    pub source_span: Option<Span>,
94}