Skip to main content

alef_core/
ir.rs

1use serde::{Deserialize, Serialize};
2
3/// Indicates the core Rust type wraps the resolved type in a smart pointer or cow.
4/// Used by codegen to generate correct From/Into conversions.
5#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
6pub enum CoreWrapper {
7    #[default]
8    None,
9    /// `Cow<'static, str>` — binding uses String, core needs `.into()`
10    Cow,
11    /// `Arc<T>` — binding unwraps, core wraps with `Arc::new()`
12    Arc,
13    /// `bytes::Bytes` — binding uses `Vec<u8>`, core needs `Bytes::from()`
14    Bytes,
15}
16
17/// Typed default value for a field, enabling backends to emit language-native defaults.
18#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
19pub enum DefaultValue {
20    BoolLiteral(bool),
21    StringLiteral(String),
22    IntLiteral(i64),
23    FloatLiteral(f64),
24    EnumVariant(String),
25    /// Empty collection or Default::default()
26    Empty,
27    /// None / null
28    None,
29}
30
31/// Complete API surface extracted from a Rust crate's public interface.
32#[derive(Debug, Clone, Serialize, Deserialize)]
33pub struct ApiSurface {
34    pub crate_name: String,
35    pub version: String,
36    pub types: Vec<TypeDef>,
37    pub functions: Vec<FunctionDef>,
38    pub enums: Vec<EnumDef>,
39    pub errors: Vec<ErrorDef>,
40}
41
42/// A public struct exposed to bindings.
43#[derive(Debug, Clone, Serialize, Deserialize)]
44pub struct TypeDef {
45    pub name: String,
46    pub rust_path: String,
47    pub fields: Vec<FieldDef>,
48    pub methods: Vec<MethodDef>,
49    pub is_opaque: bool,
50    pub is_clone: bool,
51    pub doc: String,
52    #[serde(default)]
53    pub cfg: Option<String>,
54    /// True if this type was extracted from a trait definition.
55    /// Trait types need `dyn` keyword when used as opaque inner types.
56    #[serde(default)]
57    pub is_trait: bool,
58    /// True if the type implements Default (via derive or manual impl).
59    /// Used by backends like NAPI to make all fields optional with defaults.
60    #[serde(default)]
61    pub has_default: bool,
62    /// True if some fields were stripped due to `#[cfg]` conditions.
63    /// When true, struct literal initializers need `..Default::default()` to fill
64    /// the missing fields that may exist when the core crate is compiled with features.
65    #[serde(default)]
66    pub has_stripped_cfg_fields: bool,
67    /// True if this type appears as a function return type.
68    /// Used to select output DTO style (e.g., TypedDict for Python return types).
69    #[serde(default)]
70    pub is_return_type: bool,
71    /// Serde `rename_all` strategy for this type (e.g., `"camelCase"`, `"snake_case"`).
72    /// Used by Go/Java/C# backends to emit correct JSON tags matching Rust serde config.
73    #[serde(default)]
74    pub serde_rename_all: Option<String>,
75    /// True if the type derives `serde::Serialize` and `serde::Deserialize`.
76    /// Used by FFI backend to gate `from_json`/`to_json` generation — types
77    /// without serde derives cannot be (de)serialized.
78    #[serde(default)]
79    pub has_serde: bool,
80}
81
82/// A field on a public struct.
83#[derive(Debug, Clone, Serialize, Deserialize)]
84pub struct FieldDef {
85    pub name: String,
86    pub ty: TypeRef,
87    pub optional: bool,
88    pub default: Option<String>,
89    pub doc: String,
90    /// True if this field's type was sanitized (e.g., Duration→u64, trait object→String).
91    /// Fields marked sanitized cannot participate in auto-generated From/Into conversions.
92    #[serde(default)]
93    pub sanitized: bool,
94    /// True if the core field type is `Box<T>` (or `Option<Box<T>>`).
95    /// Used by FFI backends to insert proper deref when cloning field values.
96    #[serde(default)]
97    pub is_boxed: bool,
98    /// Fully qualified Rust path for the field's type (e.g. `my_crate::types::OutputFormat`).
99    /// Used by backends to disambiguate types with the same short name.
100    #[serde(default)]
101    pub type_rust_path: Option<String>,
102    /// `#[cfg(...)]` condition string on this field, if any.
103    /// Used by backends to conditionally include fields in struct literals.
104    #[serde(default)]
105    pub cfg: Option<String>,
106    /// Typed default value for language-native default emission.
107    #[serde(default)]
108    pub typed_default: Option<DefaultValue>,
109    /// Core wrapper on this field (Cow, Arc, Bytes). Affects From/Into codegen.
110    #[serde(default)]
111    pub core_wrapper: CoreWrapper,
112    /// Core wrapper on Vec inner elements (e.g., `Vec<Arc<T>>`).
113    #[serde(default)]
114    pub vec_inner_core_wrapper: CoreWrapper,
115    /// Full Rust path of the newtype wrapper that was resolved away for this field,
116    /// e.g. `"my_crate::NodeIndex"` when `NodeIndex(u32)` was resolved to `u32`.
117    /// When set, binding→core codegen must wrap values into the newtype
118    /// (e.g. `my_crate::NodeIndex(val.field)`) and core→binding codegen must unwrap (`.0`).
119    #[serde(default)]
120    pub newtype_wrapper: Option<String>,
121}
122
123/// A method on a public struct.
124#[derive(Debug, Clone, Serialize, Deserialize)]
125pub struct MethodDef {
126    pub name: String,
127    pub params: Vec<ParamDef>,
128    pub return_type: TypeRef,
129    pub is_async: bool,
130    pub is_static: bool,
131    pub error_type: Option<String>,
132    pub doc: String,
133    pub receiver: Option<ReceiverKind>,
134    /// True if any param or return type was sanitized during unknown type resolution.
135    /// Methods with sanitized signatures cannot be auto-delegated.
136    #[serde(default)]
137    pub sanitized: bool,
138    /// Fully qualified trait path if this method comes from a trait impl
139    /// (e.g. "liter_llm::LlmClient"). None for inherent methods.
140    #[serde(default)]
141    pub trait_source: Option<String>,
142    /// True if the core function returns a reference (`&T`, `Option<&T>`, etc.).
143    /// Used by code generators to insert `.clone()` before type conversion.
144    #[serde(default)]
145    pub returns_ref: bool,
146    /// True if the core function returns `Cow<'_, T>` where T is a named type (not str/bytes).
147    /// Used by code generators to emit `.into_owned()` before type conversion.
148    #[serde(default)]
149    pub returns_cow: bool,
150    /// Full Rust path of the newtype wrapper that was resolved away for the return type,
151    /// e.g. `"my_crate::NodeIndex"` when the return type `NodeIndex(u32)` was resolved to `u32`.
152    /// When set, codegen must unwrap the returned newtype value (e.g. `result.0`) before returning.
153    #[serde(default)]
154    pub return_newtype_wrapper: Option<String>,
155}
156
157/// How `self` is received.
158#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
159pub enum ReceiverKind {
160    Ref,
161    RefMut,
162    Owned,
163}
164
165/// A free function exposed to bindings.
166#[derive(Debug, Clone, Serialize, Deserialize)]
167pub struct FunctionDef {
168    pub name: String,
169    pub rust_path: String,
170    pub params: Vec<ParamDef>,
171    pub return_type: TypeRef,
172    pub is_async: bool,
173    pub error_type: Option<String>,
174    pub doc: String,
175    #[serde(default)]
176    pub cfg: Option<String>,
177    /// True if any param or return type was sanitized during unknown type resolution.
178    #[serde(default)]
179    pub sanitized: bool,
180    /// True if the core function returns a reference (`&T`, `Option<&T>`, etc.).
181    /// Used by code generators to insert `.clone()` before type conversion.
182    #[serde(default)]
183    pub returns_ref: bool,
184    /// True if the core function returns `Cow<'_, T>` where T is a named type (not str/bytes).
185    /// Used by code generators to emit `.into_owned()` before type conversion.
186    #[serde(default)]
187    pub returns_cow: bool,
188    /// Full Rust path of the newtype wrapper that was resolved away for the return type.
189    /// When set, codegen must unwrap the returned newtype value (e.g. `result.0`).
190    #[serde(default)]
191    pub return_newtype_wrapper: Option<String>,
192}
193
194/// A function/method parameter.
195#[derive(Debug, Clone, Serialize, Deserialize)]
196pub struct ParamDef {
197    pub name: String,
198    pub ty: TypeRef,
199    pub optional: bool,
200    pub default: Option<String>,
201    /// True if this param's type was sanitized during unknown type resolution.
202    #[serde(default)]
203    pub sanitized: bool,
204    /// Typed default value for language-native default emission.
205    #[serde(default)]
206    pub typed_default: Option<DefaultValue>,
207    /// True if the original Rust parameter was a reference (`&T`).
208    /// Used by codegen to generate owned intermediates and pass refs.
209    #[serde(default)]
210    pub is_ref: bool,
211    /// True if the original Rust parameter was a mutable reference (`&mut T`).
212    /// Used by codegen to generate `&mut` refs when calling core functions.
213    #[serde(default)]
214    pub is_mut: bool,
215    /// Full Rust path of the newtype wrapper that was resolved away for this param,
216    /// e.g. `"my_crate::NodeIndex"` when `NodeIndex(u32)` was resolved to `u32`.
217    /// When set, codegen must wrap the raw value back into the newtype when calling core:
218    /// `my_crate::NodeIndex(param)` instead of just `param`.
219    #[serde(default)]
220    pub newtype_wrapper: Option<String>,
221}
222
223/// A public enum.
224#[derive(Debug, Clone, Serialize, Deserialize)]
225pub struct EnumDef {
226    pub name: String,
227    pub rust_path: String,
228    pub variants: Vec<EnumVariant>,
229    pub doc: String,
230    #[serde(default)]
231    pub cfg: Option<String>,
232    /// Serde tag property name for internally tagged enums (from `#[serde(tag = "...")]`)
233    #[serde(default, skip_serializing_if = "Option::is_none")]
234    pub serde_tag: Option<String>,
235    /// Serde rename strategy for enum variants (from `#[serde(rename_all = "...")]`)
236    #[serde(default, skip_serializing_if = "Option::is_none")]
237    pub serde_rename_all: Option<String>,
238}
239
240/// An enum variant.
241#[derive(Debug, Clone, Serialize, Deserialize)]
242pub struct EnumVariant {
243    pub name: String,
244    pub fields: Vec<FieldDef>,
245    pub doc: String,
246    /// True if this variant has `#[default]` attribute (used by `#[derive(Default)]`).
247    #[serde(default)]
248    pub is_default: bool,
249    /// Explicit serde rename for this variant (from `#[serde(rename = "...")]`).
250    #[serde(default, skip_serializing_if = "Option::is_none")]
251    pub serde_rename: Option<String>,
252}
253
254/// An error type (enum used in Result<T, E>).
255#[derive(Debug, Clone, Serialize, Deserialize)]
256pub struct ErrorDef {
257    pub name: String,
258    pub rust_path: String,
259    pub variants: Vec<ErrorVariant>,
260    pub doc: String,
261}
262
263/// An error variant.
264#[derive(Debug, Clone, Serialize, Deserialize)]
265pub struct ErrorVariant {
266    pub name: String,
267    /// The `#[error("...")]` message template string, e.g. `"I/O error: {0}"`.
268    pub message_template: Option<String>,
269    /// Fields on this variant (struct or tuple fields).
270    #[serde(default)]
271    pub fields: Vec<FieldDef>,
272    /// True if any field has `#[source]` or `#[from]`.
273    #[serde(default)]
274    pub has_source: bool,
275    /// True if any field has `#[from]` (auto From conversion).
276    #[serde(default)]
277    pub has_from: bool,
278    /// True if this is a unit variant (no fields).
279    #[serde(default)]
280    pub is_unit: bool,
281    pub doc: String,
282}
283
284/// Reference to a type, with enough info for codegen.
285#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
286pub enum TypeRef {
287    Primitive(PrimitiveType),
288    String,
289    /// Rust `char` — single Unicode character. Binding layer represents as single-char string.
290    Char,
291    Bytes,
292    Optional(Box<TypeRef>),
293    Vec(Box<TypeRef>),
294    Map(Box<TypeRef>, Box<TypeRef>),
295    Named(String),
296    Path,
297    Unit,
298    Json,
299    Duration,
300}
301
302/// Rust primitive types.
303#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
304pub enum PrimitiveType {
305    Bool,
306    U8,
307    U16,
308    U32,
309    U64,
310    I8,
311    I16,
312    I32,
313    I64,
314    F32,
315    F64,
316    Usize,
317    Isize,
318}