pub struct BamlSchemaRegistry { /* private fields */ }Expand description
Implementations§
Source§impl BamlSchemaRegistry
impl BamlSchemaRegistry
Sourcepub fn new() -> Self
pub fn new() -> Self
Create a new empty registry
Examples found in repository?
examples/nested_macro.rs (line 61)
57fn main() {
58 println!("=== Nested Structures with Macros ===\n");
59
60 // Build IR with automatic nesting resolution
61 let ir = BamlSchemaRegistry::new()
62 .register::<Role>()
63 .register::<Address>()
64 .register::<Employee>()
65 .register::<Company>()
66 .build();
67
68 println!("✅ Generated IR with {} classes and {} enums:",
69 ir.classes.len(),
70 ir.enums.len()
71 );
72 println!();
73
74 // Show what was generated
75 for enum_def in &ir.enums {
76 println!("📋 Enum: {}", enum_def.name);
77 println!(" Variants: {}", enum_def.values.join(", "));
78 println!();
79 }
80
81 for class in &ir.classes {
82 println!("📦 Class: {}", class.name);
83 for field in &class.fields {
84 let optional = if field.optional { " (optional)" } else { "" };
85 println!(" - {}: {}{}",
86 field.name,
87 field.field_type.to_string(),
88 optional
89 );
90 }
91 println!();
92 }
93
94 // Test parsing with the generated IR
95 let parser = simplify_baml::parser::Parser::new(&ir);
96
97 let test_json = r#"
98 {
99 "name": "TechCorp",
100 "employees": [
101 {
102 "name": "Alice",
103 "age": 30,
104 "role": "engineer"
105 },
106 {
107 "name": "Bob",
108 "age": 35,
109 "role": "manager"
110 }
111 ],
112 "address": {
113 "street": "123 Main St",
114 "city": "San Francisco",
115 "zipCode": "94102"
116 }
117 }
118 "#;
119
120 match parser.parse(test_json, &FieldType::Class("Company".to_string())) {
121 Ok(result) => {
122 println!("✅ Successfully parsed nested JSON!");
123 println!("{:#?}", result);
124 }
125 Err(e) => {
126 println!("❌ Parse error: {}", e);
127 }
128 }
129
130 println!("\n=== Code Comparison ===");
131 println!("Manual IR building (nested_parsing.rs): ~90 lines");
132 println!("With macros (this file): ~40 lines of definitions");
133 println!("Reduction: ~55% less code!");
134 println!("\n✨ The macro handles:");
135 println!(" • Nested structs (Company contains Address)");
136 println!(" • Lists of structs (Vec<Employee>)");
137 println!(" • Enum fields (Role in Employee)");
138 println!(" • Field renaming (zip_code → zipCode)");
139}More examples
examples/with_macros.rs (line 80)
75async fn main() -> anyhow::Result<()> {
76 println!("=== BAML Complete Macro Example ===\n");
77 println!("✨ Using all three macros for maximum productivity!\n");
78
79 // Build IR automatically from types
80 let ir = BamlSchemaRegistry::new()
81 .register::<Month>()
82 .register::<Person>()
83 .build_with_functions(vec![extract_person()]);
84
85 println!("📊 IR built with {} classes, {} enums, {} functions",
86 ir.classes.len(),
87 ir.enums.len(),
88 ir.functions.len()
89 );
90
91 // Print what was generated
92 for class in &ir.classes {
93 println!(" - Class: {} ({} fields)", class.name, class.fields.len());
94 }
95 for enum_def in &ir.enums {
96 println!(" - Enum: {} ({} variants)", enum_def.name, enum_def.values.len());
97 }
98 for func in &ir.functions {
99 println!(" - Function: {} ({} inputs -> {})",
100 func.name,
101 func.inputs.len(),
102 func.output.to_string()
103 );
104 }
105 println!();
106
107 // Configure the LLM client using macro-generated struct
108 let api_key = env::var("OPENAI_API_KEY").unwrap_or_else(|_| {
109 eprintln!("Warning: OPENAI_API_KEY not set. Using mock mode.");
110 "mock".to_string()
111 });
112
113 let client = OpenAIClient::new(api_key.clone());
114
115 // Build the runtime
116 let runtime = RuntimeBuilder::new()
117 .ir(ir)
118 .client("openai", client)
119 .build();
120
121 // Prepare input parameters
122 let mut params = HashMap::new();
123 params.insert(
124 "text".to_string(),
125 BamlValue::String(
126 "John Smith is 30 years old and was born in March. He works as a software engineer."
127 .to_string(),
128 ),
129 );
130
131 println!("Input text: {}", params.get("text").unwrap().as_string().unwrap());
132 println!("\nExecuting BAML function 'ExtractPerson'...\n");
133
134 // Execute the function
135 match runtime.execute("ExtractPerson", params).await {
136 Ok(result) => {
137 println!("✅ Success! Parsed result:");
138 print_result(&result);
139 }
140 Err(e) => {
141 eprintln!("❌ Error: {}", e);
142 eprintln!("\nNote: If you haven't set OPENAI_API_KEY, this is expected.");
143 eprintln!("Set it with: export OPENAI_API_KEY='your-key-here'");
144 }
145 }
146
147 println!("\n=== Code Comparison ===");
148 println!("Manual approach:");
149 println!(" - Class definition: ~15 lines");
150 println!(" - Enum definition: ~15 lines");
151 println!(" - Function definition: ~20 lines");
152 println!(" - Client setup: ~3 lines");
153 println!(" - Total: ~53 lines");
154 println!();
155 println!("With macros:");
156 println!(" - #[derive(BamlSchema)] on struct: ~12 lines");
157 println!(" - #[derive(BamlSchema)] on enum: ~10 lines");
158 println!(" - #[baml_function]: ~8 lines");
159 println!(" - #[derive(BamlClient)]: ~3 lines");
160 println!(" - Total: ~33 lines");
161 println!();
162 println!("💡 Savings: ~38% less code, more readable, and type-safe!");
163 println!("💡 All macros now use consistent #[derive(...)] syntax!");
164
165 Ok(())
166}examples/extract_person_macro.rs (line 60)
55async fn main() -> anyhow::Result<()> {
56 println!("=== BAML Macro Example: Extract Person ===\n");
57 println!("✨ Using #[derive(BamlSchema)] to automatically generate IR!\n");
58
59 // Step 1: Build IR using the registry - automatically collects all schema definitions
60 let ir = BamlSchemaRegistry::new()
61 .register::<Month>()
62 .register::<Person>()
63 .build_with_functions(vec![Function {
64 name: "ExtractPerson".to_string(),
65 inputs: vec![Field {
66 name: "text".to_string(),
67 field_type: FieldType::String,
68 optional: false,
69 description: Some("Text containing person information to extract".to_string()),
70 }],
71 output: FieldType::Class("Person".to_string()),
72 prompt_template: r#"Extract the person's information from the following text:
73
74{{ text }}
75
76Please extract: name, age, birth month (if mentioned), and occupation (if mentioned)."#
77 .to_string(),
78 client: "openai".to_string(),
79 }]);
80
81 println!("📊 IR built successfully with {} classes and {} enums",
82 ir.classes.len(),
83 ir.enums.len()
84 );
85
86 // Print what was generated
87 for class in &ir.classes {
88 println!(" - Class: {} ({} fields)", class.name, class.fields.len());
89 }
90 for enum_def in &ir.enums {
91 println!(" - Enum: {} ({} variants)", enum_def.name, enum_def.values.len());
92 }
93 println!();
94
95 // Step 2: Configure the LLM client
96 let api_key = env::var("OPENAI_API_KEY").unwrap_or_else(|_| {
97 eprintln!("Warning: OPENAI_API_KEY not set. Using mock response.");
98 "mock".to_string()
99 });
100
101 let client = if api_key == "mock" {
102 println!("Using mock mode (no real API calls)\n");
103 LLMClient::openai(api_key, "gpt-4o-mini".to_string())
104 } else {
105 LLMClient::openai(api_key, "gpt-4o-mini".to_string())
106 };
107
108 // Step 3: Build the runtime
109 let runtime = RuntimeBuilder::new()
110 .ir(ir)
111 .client("openai", client)
112 .build();
113
114 // Step 4: Prepare input parameters
115 let mut params = HashMap::new();
116 params.insert(
117 "text".to_string(),
118 BamlValue::String(
119 "John Smith is 30 years old and was born in March. He works as a software engineer."
120 .to_string(),
121 ),
122 );
123
124 println!(
125 "Input text: {}",
126 params.get("text").unwrap().as_string().unwrap()
127 );
128 println!("\nExecuting BAML function 'ExtractPerson'...\n");
129
130 // Step 5: Execute the function
131 match runtime.execute("ExtractPerson", params).await {
132 Ok(result) => {
133 println!("Success! Parsed result:");
134 print_result(&result);
135 }
136 Err(e) => {
137 eprintln!("Error: {}", e);
138 eprintln!("\nNote: If you haven't set OPENAI_API_KEY, this is expected.");
139 eprintln!("Set it with: export OPENAI_API_KEY='your-key-here'");
140 }
141 }
142
143 println!("\n=== Comparison ===");
144 println!("Without macros: ~70 lines of manual IR construction");
145 println!("With macros: ~25 lines of struct/enum definitions");
146 println!("Savings: Less tedious, more readable, and type-safe!");
147
148 Ok(())
149}Sourcepub fn register<T: BamlSchema>(self) -> Self
pub fn register<T: BamlSchema>(self) -> Self
Register a type that implements BamlSchema
This will automatically register the type and all its dependencies into the registry.
Examples found in repository?
examples/nested_macro.rs (line 62)
57fn main() {
58 println!("=== Nested Structures with Macros ===\n");
59
60 // Build IR with automatic nesting resolution
61 let ir = BamlSchemaRegistry::new()
62 .register::<Role>()
63 .register::<Address>()
64 .register::<Employee>()
65 .register::<Company>()
66 .build();
67
68 println!("✅ Generated IR with {} classes and {} enums:",
69 ir.classes.len(),
70 ir.enums.len()
71 );
72 println!();
73
74 // Show what was generated
75 for enum_def in &ir.enums {
76 println!("📋 Enum: {}", enum_def.name);
77 println!(" Variants: {}", enum_def.values.join(", "));
78 println!();
79 }
80
81 for class in &ir.classes {
82 println!("📦 Class: {}", class.name);
83 for field in &class.fields {
84 let optional = if field.optional { " (optional)" } else { "" };
85 println!(" - {}: {}{}",
86 field.name,
87 field.field_type.to_string(),
88 optional
89 );
90 }
91 println!();
92 }
93
94 // Test parsing with the generated IR
95 let parser = simplify_baml::parser::Parser::new(&ir);
96
97 let test_json = r#"
98 {
99 "name": "TechCorp",
100 "employees": [
101 {
102 "name": "Alice",
103 "age": 30,
104 "role": "engineer"
105 },
106 {
107 "name": "Bob",
108 "age": 35,
109 "role": "manager"
110 }
111 ],
112 "address": {
113 "street": "123 Main St",
114 "city": "San Francisco",
115 "zipCode": "94102"
116 }
117 }
118 "#;
119
120 match parser.parse(test_json, &FieldType::Class("Company".to_string())) {
121 Ok(result) => {
122 println!("✅ Successfully parsed nested JSON!");
123 println!("{:#?}", result);
124 }
125 Err(e) => {
126 println!("❌ Parse error: {}", e);
127 }
128 }
129
130 println!("\n=== Code Comparison ===");
131 println!("Manual IR building (nested_parsing.rs): ~90 lines");
132 println!("With macros (this file): ~40 lines of definitions");
133 println!("Reduction: ~55% less code!");
134 println!("\n✨ The macro handles:");
135 println!(" • Nested structs (Company contains Address)");
136 println!(" • Lists of structs (Vec<Employee>)");
137 println!(" • Enum fields (Role in Employee)");
138 println!(" • Field renaming (zip_code → zipCode)");
139}More examples
examples/with_macros.rs (line 81)
75async fn main() -> anyhow::Result<()> {
76 println!("=== BAML Complete Macro Example ===\n");
77 println!("✨ Using all three macros for maximum productivity!\n");
78
79 // Build IR automatically from types
80 let ir = BamlSchemaRegistry::new()
81 .register::<Month>()
82 .register::<Person>()
83 .build_with_functions(vec![extract_person()]);
84
85 println!("📊 IR built with {} classes, {} enums, {} functions",
86 ir.classes.len(),
87 ir.enums.len(),
88 ir.functions.len()
89 );
90
91 // Print what was generated
92 for class in &ir.classes {
93 println!(" - Class: {} ({} fields)", class.name, class.fields.len());
94 }
95 for enum_def in &ir.enums {
96 println!(" - Enum: {} ({} variants)", enum_def.name, enum_def.values.len());
97 }
98 for func in &ir.functions {
99 println!(" - Function: {} ({} inputs -> {})",
100 func.name,
101 func.inputs.len(),
102 func.output.to_string()
103 );
104 }
105 println!();
106
107 // Configure the LLM client using macro-generated struct
108 let api_key = env::var("OPENAI_API_KEY").unwrap_or_else(|_| {
109 eprintln!("Warning: OPENAI_API_KEY not set. Using mock mode.");
110 "mock".to_string()
111 });
112
113 let client = OpenAIClient::new(api_key.clone());
114
115 // Build the runtime
116 let runtime = RuntimeBuilder::new()
117 .ir(ir)
118 .client("openai", client)
119 .build();
120
121 // Prepare input parameters
122 let mut params = HashMap::new();
123 params.insert(
124 "text".to_string(),
125 BamlValue::String(
126 "John Smith is 30 years old and was born in March. He works as a software engineer."
127 .to_string(),
128 ),
129 );
130
131 println!("Input text: {}", params.get("text").unwrap().as_string().unwrap());
132 println!("\nExecuting BAML function 'ExtractPerson'...\n");
133
134 // Execute the function
135 match runtime.execute("ExtractPerson", params).await {
136 Ok(result) => {
137 println!("✅ Success! Parsed result:");
138 print_result(&result);
139 }
140 Err(e) => {
141 eprintln!("❌ Error: {}", e);
142 eprintln!("\nNote: If you haven't set OPENAI_API_KEY, this is expected.");
143 eprintln!("Set it with: export OPENAI_API_KEY='your-key-here'");
144 }
145 }
146
147 println!("\n=== Code Comparison ===");
148 println!("Manual approach:");
149 println!(" - Class definition: ~15 lines");
150 println!(" - Enum definition: ~15 lines");
151 println!(" - Function definition: ~20 lines");
152 println!(" - Client setup: ~3 lines");
153 println!(" - Total: ~53 lines");
154 println!();
155 println!("With macros:");
156 println!(" - #[derive(BamlSchema)] on struct: ~12 lines");
157 println!(" - #[derive(BamlSchema)] on enum: ~10 lines");
158 println!(" - #[baml_function]: ~8 lines");
159 println!(" - #[derive(BamlClient)]: ~3 lines");
160 println!(" - Total: ~33 lines");
161 println!();
162 println!("💡 Savings: ~38% less code, more readable, and type-safe!");
163 println!("💡 All macros now use consistent #[derive(...)] syntax!");
164
165 Ok(())
166}examples/extract_person_macro.rs (line 61)
55async fn main() -> anyhow::Result<()> {
56 println!("=== BAML Macro Example: Extract Person ===\n");
57 println!("✨ Using #[derive(BamlSchema)] to automatically generate IR!\n");
58
59 // Step 1: Build IR using the registry - automatically collects all schema definitions
60 let ir = BamlSchemaRegistry::new()
61 .register::<Month>()
62 .register::<Person>()
63 .build_with_functions(vec![Function {
64 name: "ExtractPerson".to_string(),
65 inputs: vec![Field {
66 name: "text".to_string(),
67 field_type: FieldType::String,
68 optional: false,
69 description: Some("Text containing person information to extract".to_string()),
70 }],
71 output: FieldType::Class("Person".to_string()),
72 prompt_template: r#"Extract the person's information from the following text:
73
74{{ text }}
75
76Please extract: name, age, birth month (if mentioned), and occupation (if mentioned)."#
77 .to_string(),
78 client: "openai".to_string(),
79 }]);
80
81 println!("📊 IR built successfully with {} classes and {} enums",
82 ir.classes.len(),
83 ir.enums.len()
84 );
85
86 // Print what was generated
87 for class in &ir.classes {
88 println!(" - Class: {} ({} fields)", class.name, class.fields.len());
89 }
90 for enum_def in &ir.enums {
91 println!(" - Enum: {} ({} variants)", enum_def.name, enum_def.values.len());
92 }
93 println!();
94
95 // Step 2: Configure the LLM client
96 let api_key = env::var("OPENAI_API_KEY").unwrap_or_else(|_| {
97 eprintln!("Warning: OPENAI_API_KEY not set. Using mock response.");
98 "mock".to_string()
99 });
100
101 let client = if api_key == "mock" {
102 println!("Using mock mode (no real API calls)\n");
103 LLMClient::openai(api_key, "gpt-4o-mini".to_string())
104 } else {
105 LLMClient::openai(api_key, "gpt-4o-mini".to_string())
106 };
107
108 // Step 3: Build the runtime
109 let runtime = RuntimeBuilder::new()
110 .ir(ir)
111 .client("openai", client)
112 .build();
113
114 // Step 4: Prepare input parameters
115 let mut params = HashMap::new();
116 params.insert(
117 "text".to_string(),
118 BamlValue::String(
119 "John Smith is 30 years old and was born in March. He works as a software engineer."
120 .to_string(),
121 ),
122 );
123
124 println!(
125 "Input text: {}",
126 params.get("text").unwrap().as_string().unwrap()
127 );
128 println!("\nExecuting BAML function 'ExtractPerson'...\n");
129
130 // Step 5: Execute the function
131 match runtime.execute("ExtractPerson", params).await {
132 Ok(result) => {
133 println!("Success! Parsed result:");
134 print_result(&result);
135 }
136 Err(e) => {
137 eprintln!("Error: {}", e);
138 eprintln!("\nNote: If you haven't set OPENAI_API_KEY, this is expected.");
139 eprintln!("Set it with: export OPENAI_API_KEY='your-key-here'");
140 }
141 }
142
143 println!("\n=== Comparison ===");
144 println!("Without macros: ~70 lines of manual IR construction");
145 println!("With macros: ~25 lines of struct/enum definitions");
146 println!("Savings: Less tedious, more readable, and type-safe!");
147
148 Ok(())
149}Sourcepub fn add_class(&mut self, class: Class)
pub fn add_class(&mut self, class: Class)
Add a class to the registry (called by the derive macro)
Sourcepub fn add_enum(&mut self, enum_def: Enum)
pub fn add_enum(&mut self, enum_def: Enum)
Add an enum to the registry (called by the derive macro)
Sourcepub fn build(self) -> IR
pub fn build(self) -> IR
Build the final IR from all registered types
Examples found in repository?
examples/nested_macro.rs (line 66)
57fn main() {
58 println!("=== Nested Structures with Macros ===\n");
59
60 // Build IR with automatic nesting resolution
61 let ir = BamlSchemaRegistry::new()
62 .register::<Role>()
63 .register::<Address>()
64 .register::<Employee>()
65 .register::<Company>()
66 .build();
67
68 println!("✅ Generated IR with {} classes and {} enums:",
69 ir.classes.len(),
70 ir.enums.len()
71 );
72 println!();
73
74 // Show what was generated
75 for enum_def in &ir.enums {
76 println!("📋 Enum: {}", enum_def.name);
77 println!(" Variants: {}", enum_def.values.join(", "));
78 println!();
79 }
80
81 for class in &ir.classes {
82 println!("📦 Class: {}", class.name);
83 for field in &class.fields {
84 let optional = if field.optional { " (optional)" } else { "" };
85 println!(" - {}: {}{}",
86 field.name,
87 field.field_type.to_string(),
88 optional
89 );
90 }
91 println!();
92 }
93
94 // Test parsing with the generated IR
95 let parser = simplify_baml::parser::Parser::new(&ir);
96
97 let test_json = r#"
98 {
99 "name": "TechCorp",
100 "employees": [
101 {
102 "name": "Alice",
103 "age": 30,
104 "role": "engineer"
105 },
106 {
107 "name": "Bob",
108 "age": 35,
109 "role": "manager"
110 }
111 ],
112 "address": {
113 "street": "123 Main St",
114 "city": "San Francisco",
115 "zipCode": "94102"
116 }
117 }
118 "#;
119
120 match parser.parse(test_json, &FieldType::Class("Company".to_string())) {
121 Ok(result) => {
122 println!("✅ Successfully parsed nested JSON!");
123 println!("{:#?}", result);
124 }
125 Err(e) => {
126 println!("❌ Parse error: {}", e);
127 }
128 }
129
130 println!("\n=== Code Comparison ===");
131 println!("Manual IR building (nested_parsing.rs): ~90 lines");
132 println!("With macros (this file): ~40 lines of definitions");
133 println!("Reduction: ~55% less code!");
134 println!("\n✨ The macro handles:");
135 println!(" • Nested structs (Company contains Address)");
136 println!(" • Lists of structs (Vec<Employee>)");
137 println!(" • Enum fields (Role in Employee)");
138 println!(" • Field renaming (zip_code → zipCode)");
139}Sourcepub fn build_with_functions(self, functions: Vec<Function>) -> IR
pub fn build_with_functions(self, functions: Vec<Function>) -> IR
Build IR and include additional functions
Examples found in repository?
examples/with_macros.rs (line 83)
75async fn main() -> anyhow::Result<()> {
76 println!("=== BAML Complete Macro Example ===\n");
77 println!("✨ Using all three macros for maximum productivity!\n");
78
79 // Build IR automatically from types
80 let ir = BamlSchemaRegistry::new()
81 .register::<Month>()
82 .register::<Person>()
83 .build_with_functions(vec![extract_person()]);
84
85 println!("📊 IR built with {} classes, {} enums, {} functions",
86 ir.classes.len(),
87 ir.enums.len(),
88 ir.functions.len()
89 );
90
91 // Print what was generated
92 for class in &ir.classes {
93 println!(" - Class: {} ({} fields)", class.name, class.fields.len());
94 }
95 for enum_def in &ir.enums {
96 println!(" - Enum: {} ({} variants)", enum_def.name, enum_def.values.len());
97 }
98 for func in &ir.functions {
99 println!(" - Function: {} ({} inputs -> {})",
100 func.name,
101 func.inputs.len(),
102 func.output.to_string()
103 );
104 }
105 println!();
106
107 // Configure the LLM client using macro-generated struct
108 let api_key = env::var("OPENAI_API_KEY").unwrap_or_else(|_| {
109 eprintln!("Warning: OPENAI_API_KEY not set. Using mock mode.");
110 "mock".to_string()
111 });
112
113 let client = OpenAIClient::new(api_key.clone());
114
115 // Build the runtime
116 let runtime = RuntimeBuilder::new()
117 .ir(ir)
118 .client("openai", client)
119 .build();
120
121 // Prepare input parameters
122 let mut params = HashMap::new();
123 params.insert(
124 "text".to_string(),
125 BamlValue::String(
126 "John Smith is 30 years old and was born in March. He works as a software engineer."
127 .to_string(),
128 ),
129 );
130
131 println!("Input text: {}", params.get("text").unwrap().as_string().unwrap());
132 println!("\nExecuting BAML function 'ExtractPerson'...\n");
133
134 // Execute the function
135 match runtime.execute("ExtractPerson", params).await {
136 Ok(result) => {
137 println!("✅ Success! Parsed result:");
138 print_result(&result);
139 }
140 Err(e) => {
141 eprintln!("❌ Error: {}", e);
142 eprintln!("\nNote: If you haven't set OPENAI_API_KEY, this is expected.");
143 eprintln!("Set it with: export OPENAI_API_KEY='your-key-here'");
144 }
145 }
146
147 println!("\n=== Code Comparison ===");
148 println!("Manual approach:");
149 println!(" - Class definition: ~15 lines");
150 println!(" - Enum definition: ~15 lines");
151 println!(" - Function definition: ~20 lines");
152 println!(" - Client setup: ~3 lines");
153 println!(" - Total: ~53 lines");
154 println!();
155 println!("With macros:");
156 println!(" - #[derive(BamlSchema)] on struct: ~12 lines");
157 println!(" - #[derive(BamlSchema)] on enum: ~10 lines");
158 println!(" - #[baml_function]: ~8 lines");
159 println!(" - #[derive(BamlClient)]: ~3 lines");
160 println!(" - Total: ~33 lines");
161 println!();
162 println!("💡 Savings: ~38% less code, more readable, and type-safe!");
163 println!("💡 All macros now use consistent #[derive(...)] syntax!");
164
165 Ok(())
166}More examples
examples/extract_person_macro.rs (lines 63-79)
55async fn main() -> anyhow::Result<()> {
56 println!("=== BAML Macro Example: Extract Person ===\n");
57 println!("✨ Using #[derive(BamlSchema)] to automatically generate IR!\n");
58
59 // Step 1: Build IR using the registry - automatically collects all schema definitions
60 let ir = BamlSchemaRegistry::new()
61 .register::<Month>()
62 .register::<Person>()
63 .build_with_functions(vec![Function {
64 name: "ExtractPerson".to_string(),
65 inputs: vec![Field {
66 name: "text".to_string(),
67 field_type: FieldType::String,
68 optional: false,
69 description: Some("Text containing person information to extract".to_string()),
70 }],
71 output: FieldType::Class("Person".to_string()),
72 prompt_template: r#"Extract the person's information from the following text:
73
74{{ text }}
75
76Please extract: name, age, birth month (if mentioned), and occupation (if mentioned)."#
77 .to_string(),
78 client: "openai".to_string(),
79 }]);
80
81 println!("📊 IR built successfully with {} classes and {} enums",
82 ir.classes.len(),
83 ir.enums.len()
84 );
85
86 // Print what was generated
87 for class in &ir.classes {
88 println!(" - Class: {} ({} fields)", class.name, class.fields.len());
89 }
90 for enum_def in &ir.enums {
91 println!(" - Enum: {} ({} variants)", enum_def.name, enum_def.values.len());
92 }
93 println!();
94
95 // Step 2: Configure the LLM client
96 let api_key = env::var("OPENAI_API_KEY").unwrap_or_else(|_| {
97 eprintln!("Warning: OPENAI_API_KEY not set. Using mock response.");
98 "mock".to_string()
99 });
100
101 let client = if api_key == "mock" {
102 println!("Using mock mode (no real API calls)\n");
103 LLMClient::openai(api_key, "gpt-4o-mini".to_string())
104 } else {
105 LLMClient::openai(api_key, "gpt-4o-mini".to_string())
106 };
107
108 // Step 3: Build the runtime
109 let runtime = RuntimeBuilder::new()
110 .ir(ir)
111 .client("openai", client)
112 .build();
113
114 // Step 4: Prepare input parameters
115 let mut params = HashMap::new();
116 params.insert(
117 "text".to_string(),
118 BamlValue::String(
119 "John Smith is 30 years old and was born in March. He works as a software engineer."
120 .to_string(),
121 ),
122 );
123
124 println!(
125 "Input text: {}",
126 params.get("text").unwrap().as_string().unwrap()
127 );
128 println!("\nExecuting BAML function 'ExtractPerson'...\n");
129
130 // Step 5: Execute the function
131 match runtime.execute("ExtractPerson", params).await {
132 Ok(result) => {
133 println!("Success! Parsed result:");
134 print_result(&result);
135 }
136 Err(e) => {
137 eprintln!("Error: {}", e);
138 eprintln!("\nNote: If you haven't set OPENAI_API_KEY, this is expected.");
139 eprintln!("Set it with: export OPENAI_API_KEY='your-key-here'");
140 }
141 }
142
143 println!("\n=== Comparison ===");
144 println!("Without macros: ~70 lines of manual IR construction");
145 println!("With macros: ~25 lines of struct/enum definitions");
146 println!("Savings: Less tedious, more readable, and type-safe!");
147
148 Ok(())
149}Trait Implementations§
Auto Trait Implementations§
impl Freeze for BamlSchemaRegistry
impl RefUnwindSafe for BamlSchemaRegistry
impl Send for BamlSchemaRegistry
impl Sync for BamlSchemaRegistry
impl Unpin for BamlSchemaRegistry
impl UnwindSafe for BamlSchemaRegistry
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more