oslquery_petite/parser/
types.rs

1//! Intermediate types for parsing OSO files.
2//!
3//! These types are used during parsing and are converted to the final
4//! type-safe representations after parsing is complete.
5
6use ustr::Ustr;
7
8/// Base type enumeration matching OSL's type system.
9#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10pub enum BaseType {
11    None,
12    Int,
13    Float,
14    String,
15    Color,
16    Point,
17    Vector,
18    Normal,
19    Matrix,
20}
21
22impl BaseType {
23    /// Returns the number of components for aggregate types.
24    pub fn components(&self) -> usize {
25        match self {
26            BaseType::None | BaseType::Int | BaseType::Float | BaseType::String => 1,
27            BaseType::Color | BaseType::Point | BaseType::Vector | BaseType::Normal => 3,
28            BaseType::Matrix => 16,
29        }
30    }
31
32    /// Convert to string representation
33    pub fn as_str(&self) -> &'static str {
34        match self {
35            BaseType::None => "none",
36            BaseType::Int => "int",
37            BaseType::Float => "float",
38            BaseType::String => "string",
39            BaseType::Color => "color",
40            BaseType::Point => "point",
41            BaseType::Vector => "vector",
42            BaseType::Normal => "normal",
43            BaseType::Matrix => "matrix",
44        }
45    }
46}
47
48impl std::str::FromStr for BaseType {
49    type Err = String;
50
51    fn from_str(s: &str) -> Result<Self, Self::Err> {
52        match s {
53            "int" => Ok(BaseType::Int),
54            "float" => Ok(BaseType::Float),
55            "string" => Ok(BaseType::String),
56            "color" => Ok(BaseType::Color),
57            "point" => Ok(BaseType::Point),
58            "vector" => Ok(BaseType::Vector),
59            "normal" => Ok(BaseType::Normal),
60            "matrix" => Ok(BaseType::Matrix),
61            _ => Err(format!("Unknown base type: {}", s)),
62        }
63    }
64}
65
66/// Type descriptor for parsing.
67#[derive(Debug, Clone, Copy, PartialEq, Eq)]
68pub struct TypeDesc {
69    pub basetype: BaseType,
70    pub arraylen: i32,
71    pub is_closure: bool,
72}
73
74impl TypeDesc {
75    pub fn new(basetype: BaseType) -> Self {
76        TypeDesc {
77            basetype,
78            arraylen: 0,
79            is_closure: false,
80        }
81    }
82
83    pub fn new_array(basetype: BaseType, arraylen: i32) -> Self {
84        TypeDesc {
85            basetype,
86            arraylen,
87            is_closure: false,
88        }
89    }
90
91    pub fn is_array(&self) -> bool {
92        self.arraylen != 0
93    }
94
95    pub fn is_unsized_array(&self) -> bool {
96        self.arraylen == -1
97    }
98}
99
100/// Symbol type for OSL symbols.
101#[derive(Debug, Clone, Copy, PartialEq, Eq)]
102pub enum SymType {
103    Param,
104    OutputParam,
105    Local,
106    Temp,
107    Global,
108    Const,
109}
110
111/// Type specification used during parsing.
112#[derive(Debug, Clone, PartialEq, Eq)]
113pub struct TypeSpec {
114    pub simpletype: TypeDesc,
115    pub structure: i16,
116}
117
118impl TypeSpec {
119    pub fn new(simpletype: TypeDesc) -> Self {
120        TypeSpec {
121            simpletype,
122            structure: 0,
123        }
124    }
125
126    pub fn is_structure(&self) -> bool {
127        self.structure > 0
128    }
129
130    pub fn is_closure(&self) -> bool {
131        self.simpletype.is_closure
132    }
133
134    pub fn is_unsized_array(&self) -> bool {
135        self.simpletype.is_unsized_array()
136    }
137}
138
139/// Intermediate parameter structure for parsing.
140#[derive(Debug, Clone)]
141pub struct ParsedParameter {
142    pub name: Ustr,
143    pub type_desc: TypeDesc,
144    pub is_output: bool,
145    pub is_struct: bool,
146    pub valid_default: bool,
147    pub varlen_array: bool,
148
149    pub idefault: Vec<i32>,
150    pub fdefault: Vec<f32>,
151    pub sdefault: Vec<String>,
152
153    pub spacename: Vec<String>,
154    pub structname: Option<Ustr>,
155    pub fields: Vec<Ustr>,
156    pub metadata: Vec<ParsedParameter>,
157}
158
159impl ParsedParameter {
160    pub fn new(name: impl Into<Ustr>, type_desc: TypeDesc) -> Self {
161        ParsedParameter {
162            name: name.into(),
163            type_desc,
164            is_output: false,
165            is_struct: false,
166            valid_default: false,
167            varlen_array: false,
168            idefault: Vec::new(),
169            fdefault: Vec::new(),
170            sdefault: Vec::new(),
171            spacename: Vec::new(),
172            structname: None,
173            fields: Vec::new(),
174            metadata: Vec::new(),
175        }
176    }
177
178    pub fn find_metadata(&self, name: &str) -> Option<&ParsedParameter> {
179        self.metadata.iter().find(|m| m.name.as_str() == name)
180    }
181}