Skip to main content

alef_core/
ir.rs

1use serde::{Deserialize, Serialize};
2
3/// Typed default value for a field, enabling backends to emit language-native defaults.
4#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
5pub enum DefaultValue {
6    BoolLiteral(bool),
7    StringLiteral(String),
8    IntLiteral(i64),
9    FloatLiteral(f64),
10    EnumVariant(String),
11    /// Empty collection or Default::default()
12    Empty,
13    /// None / null
14    None,
15}
16
17/// Complete API surface extracted from a Rust crate's public interface.
18#[derive(Debug, Clone, Serialize, Deserialize)]
19pub struct ApiSurface {
20    pub crate_name: String,
21    pub version: String,
22    pub types: Vec<TypeDef>,
23    pub functions: Vec<FunctionDef>,
24    pub enums: Vec<EnumDef>,
25    pub errors: Vec<ErrorDef>,
26}
27
28/// A public struct exposed to bindings.
29#[derive(Debug, Clone, Serialize, Deserialize)]
30pub struct TypeDef {
31    pub name: String,
32    pub rust_path: String,
33    pub fields: Vec<FieldDef>,
34    pub methods: Vec<MethodDef>,
35    pub is_opaque: bool,
36    pub is_clone: bool,
37    pub doc: String,
38    #[serde(default)]
39    pub cfg: Option<String>,
40    /// True if this type was extracted from a trait definition.
41    /// Trait types need `dyn` keyword when used as opaque inner types.
42    #[serde(default)]
43    pub is_trait: bool,
44    /// True if the type implements Default (via derive or manual impl).
45    /// Used by backends like NAPI to make all fields optional with defaults.
46    #[serde(default)]
47    pub has_default: bool,
48    /// True if some fields were stripped due to `#[cfg]` conditions.
49    /// When true, struct literal initializers need `..Default::default()` to fill
50    /// the missing fields that may exist when the core crate is compiled with features.
51    #[serde(default)]
52    pub has_stripped_cfg_fields: bool,
53    /// True if this type appears as a function return type.
54    /// Used to select output DTO style (e.g., TypedDict for Python return types).
55    #[serde(default)]
56    pub is_return_type: bool,
57}
58
59/// A field on a public struct.
60#[derive(Debug, Clone, Serialize, Deserialize)]
61pub struct FieldDef {
62    pub name: String,
63    pub ty: TypeRef,
64    pub optional: bool,
65    pub default: Option<String>,
66    pub doc: String,
67    /// True if this field's type was sanitized (e.g., Duration→u64, trait object→String).
68    /// Fields marked sanitized cannot participate in auto-generated From/Into conversions.
69    #[serde(default)]
70    pub sanitized: bool,
71    /// True if the core field type is `Box<T>` (or `Option<Box<T>>`).
72    /// Used by FFI backends to insert proper deref when cloning field values.
73    #[serde(default)]
74    pub is_boxed: bool,
75    /// Fully qualified Rust path for the field's type (e.g. `my_crate::types::OutputFormat`).
76    /// Used by backends to disambiguate types with the same short name.
77    #[serde(default)]
78    pub type_rust_path: Option<String>,
79    /// `#[cfg(...)]` condition string on this field, if any.
80    /// Used by backends to conditionally include fields in struct literals.
81    #[serde(default)]
82    pub cfg: Option<String>,
83    /// Typed default value for language-native default emission.
84    #[serde(default)]
85    pub typed_default: Option<DefaultValue>,
86}
87
88/// A method on a public struct.
89#[derive(Debug, Clone, Serialize, Deserialize)]
90pub struct MethodDef {
91    pub name: String,
92    pub params: Vec<ParamDef>,
93    pub return_type: TypeRef,
94    pub is_async: bool,
95    pub is_static: bool,
96    pub error_type: Option<String>,
97    pub doc: String,
98    pub receiver: Option<ReceiverKind>,
99    /// True if any param or return type was sanitized during unknown type resolution.
100    /// Methods with sanitized signatures cannot be auto-delegated.
101    #[serde(default)]
102    pub sanitized: bool,
103    /// Fully qualified trait path if this method comes from a trait impl
104    /// (e.g. "liter_llm::LlmClient"). None for inherent methods.
105    #[serde(default)]
106    pub trait_source: Option<String>,
107    /// True if the core function returns a reference (`&T`, `Option<&T>`, etc.).
108    /// Used by code generators to insert `.clone()` before type conversion.
109    #[serde(default)]
110    pub returns_ref: bool,
111}
112
113/// How `self` is received.
114#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
115pub enum ReceiverKind {
116    Ref,
117    RefMut,
118    Owned,
119}
120
121/// A free function exposed to bindings.
122#[derive(Debug, Clone, Serialize, Deserialize)]
123pub struct FunctionDef {
124    pub name: String,
125    pub rust_path: String,
126    pub params: Vec<ParamDef>,
127    pub return_type: TypeRef,
128    pub is_async: bool,
129    pub error_type: Option<String>,
130    pub doc: String,
131    #[serde(default)]
132    pub cfg: Option<String>,
133    /// True if any param or return type was sanitized during unknown type resolution.
134    #[serde(default)]
135    pub sanitized: bool,
136    /// True if the core function returns a reference (`&T`, `Option<&T>`, etc.).
137    /// Used by code generators to insert `.clone()` before type conversion.
138    #[serde(default)]
139    pub returns_ref: bool,
140}
141
142/// A function/method parameter.
143#[derive(Debug, Clone, Serialize, Deserialize)]
144pub struct ParamDef {
145    pub name: String,
146    pub ty: TypeRef,
147    pub optional: bool,
148    pub default: Option<String>,
149    /// True if this param's type was sanitized during unknown type resolution.
150    #[serde(default)]
151    pub sanitized: bool,
152    /// Typed default value for language-native default emission.
153    #[serde(default)]
154    pub typed_default: Option<DefaultValue>,
155}
156
157/// A public enum.
158#[derive(Debug, Clone, Serialize, Deserialize)]
159pub struct EnumDef {
160    pub name: String,
161    pub rust_path: String,
162    pub variants: Vec<EnumVariant>,
163    pub doc: String,
164    #[serde(default)]
165    pub cfg: Option<String>,
166}
167
168/// An enum variant.
169#[derive(Debug, Clone, Serialize, Deserialize)]
170pub struct EnumVariant {
171    pub name: String,
172    pub fields: Vec<FieldDef>,
173    pub doc: String,
174    /// True if this variant has `#[default]` attribute (used by `#[derive(Default)]`).
175    #[serde(default)]
176    pub is_default: bool,
177}
178
179/// An error type (enum used in Result<T, E>).
180#[derive(Debug, Clone, Serialize, Deserialize)]
181pub struct ErrorDef {
182    pub name: String,
183    pub rust_path: String,
184    pub variants: Vec<ErrorVariant>,
185    pub doc: String,
186}
187
188/// An error variant.
189#[derive(Debug, Clone, Serialize, Deserialize)]
190pub struct ErrorVariant {
191    pub name: String,
192    /// The `#[error("...")]` message template string, e.g. `"I/O error: {0}"`.
193    pub message_template: Option<String>,
194    /// Fields on this variant (struct or tuple fields).
195    #[serde(default)]
196    pub fields: Vec<FieldDef>,
197    /// True if any field has `#[source]` or `#[from]`.
198    #[serde(default)]
199    pub has_source: bool,
200    /// True if any field has `#[from]` (auto From conversion).
201    #[serde(default)]
202    pub has_from: bool,
203    /// True if this is a unit variant (no fields).
204    #[serde(default)]
205    pub is_unit: bool,
206    pub doc: String,
207}
208
209/// Reference to a type, with enough info for codegen.
210#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
211pub enum TypeRef {
212    Primitive(PrimitiveType),
213    String,
214    /// Rust `char` — single Unicode character. Binding layer represents as single-char string.
215    Char,
216    Bytes,
217    Optional(Box<TypeRef>),
218    Vec(Box<TypeRef>),
219    Map(Box<TypeRef>, Box<TypeRef>),
220    Named(String),
221    Path,
222    Unit,
223    Json,
224    Duration,
225}
226
227/// Rust primitive types.
228#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
229pub enum PrimitiveType {
230    Bool,
231    U8,
232    U16,
233    U32,
234    U64,
235    I8,
236    I16,
237    I32,
238    I64,
239    F32,
240    F64,
241    Usize,
242    Isize,
243}