pub struct ApiExecutor<C> { /* private fields */ }Expand description
A stateful executor for API operations that maintains context across multiple calls.
ImplementationsΒ§
SourceΒ§impl<C> ApiExecutor<C>
impl<C> ApiExecutor<C>
Sourcepub fn new(context: C) -> Self
pub fn new(context: C) -> Self
Creates a new ApiExecutor that owns the provided context.
Examples found in repository?
examples/executor_pattern.rs (line 218)
213fn main() {
214 println!("π§ ApiThing Executor Pattern Example");
215 println!("====================================\n");
216
217 // Create an executor that manages the context for us
218 let mut executor = ApiExecutor::new(AppContext::new("production_db".to_string()));
219
220 println!("ποΈ Created ApiExecutor with context");
221 println!("π Connection: {}", executor.context().connection_pool());
222 println!(
223 "π’ Initial transaction count: {}\n",
224 executor.context().transaction_count()
225 );
226
227 // === User Operations ===
228 println!("π₯ USER OPERATIONS");
229 println!("==================");
230
231 // Create multiple users using the executor
232 let users = vec![
233 ("Alice Johnson", "alice@company.com"),
234 ("Bob Smith", "bob@company.com"),
235 ("Carol Davis", "carol@company.com"),
236 ];
237
238 let mut created_users = Vec::new();
239 for (name, email) in users {
240 match executor.execute(
241 CreateUser,
242 &CreateUserProps {
243 name: name.to_string(),
244 email: email.to_string(),
245 },
246 ) {
247 Ok(user) => {
248 println!("β
Created user: {} (ID: {})", user.name, user.id);
249 created_users.push(user);
250 }
251 Err(e) => {
252 println!("β Failed to create user {}: {:?}", name, e);
253 return;
254 }
255 }
256 }
257
258 println!(
259 "π’ Transaction count after user creation: {}\n",
260 executor.context().transaction_count()
261 );
262
263 // === Product Operations (Same Context) ===
264 println!("π¦ PRODUCT OPERATIONS");
265 println!("====================");
266
267 // Create products using the same executor/context
268 let products = vec![
269 ("Laptop Pro", 1299.99, "Electronics"),
270 ("Office Chair", 249.50, "Furniture"),
271 ("Coffee Mug", 12.99, "Kitchen"),
272 ];
273
274 let mut created_products = Vec::new();
275 for (name, price, category) in products {
276 match executor.execute(
277 CreateProduct,
278 &CreateProductProps {
279 name: name.to_string(),
280 price,
281 category: category.to_string(),
282 },
283 ) {
284 Ok(product) => {
285 println!(
286 "β
Created product: {} (ID: {}, Price: ${:.2})",
287 product.name, product.id, product.price
288 );
289 created_products.push(product);
290 }
291 Err(e) => {
292 println!("β Failed to create product {}: {:?}", name, e);
293 return;
294 }
295 }
296 }
297
298 println!(
299 "π’ Transaction count after product creation: {}\n",
300 executor.context().transaction_count()
301 );
302
303 // === Cross-Family Operations ===
304 println!("π CROSS-FAMILY LOOKUPS");
305 println!("=======================");
306
307 // Find users and products using the same context
308 // This demonstrates how the cache works across different API families
309
310 println!("π Looking up created entities...");
311
312 // Find first user
313 if let Some(user) = created_users.first() {
314 match executor.execute(FindUser, &FindUserProps { user_id: user.id }) {
315 Ok(found_user) => println!("π€ Found user: {} ({})", found_user.name, found_user.email),
316 Err(e) => println!("β Failed to find user: {:?}", e),
317 }
318 }
319
320 // Find first product
321 if let Some(product) = created_products.first() {
322 match executor.execute(
323 FindProduct,
324 &FindProductProps {
325 product_id: product.id,
326 },
327 ) {
328 Ok(found_product) => println!(
329 "π¦ Found product: {} (${:.2})",
330 found_product.name, found_product.price
331 ),
332 Err(e) => println!("β Failed to find product: {:?}", e),
333 }
334 }
335
336 // === Context Inspection ===
337 println!("\nπ CONTEXT INSPECTION");
338 println!("=====================");
339
340 let context = executor.context();
341 println!(
342 "π’ Final transaction count: {}",
343 context.transaction_count()
344 );
345 println!("πΎ Cache entries: {} items", context.cache().len());
346
347 // Show cache contents
348 println!("π Cached items:");
349 for (key, value) in context.cache().iter() {
350 // Truncate long values for display
351 let display_value = if value.len() > 50 {
352 format!("{}...", &value[..47])
353 } else {
354 value.clone()
355 };
356 println!(" β’ {}: {}", key, display_value);
357 }
358
359 // === Executor Benefits Demo ===
360 println!("\nπ‘ EXECUTOR BENEFITS");
361 println!("====================");
362
363 // Show how we can access the context for debugging or inspection
364 let final_context = executor.context();
365 println!("β
Centralized state management:");
366 println!(
367 " β’ {} total operations executed",
368 final_context.transaction_count()
369 );
370 println!(" β’ {} entities cached", final_context.cache().len());
371 println!(" β’ Single context shared across {} API families", 2);
372
373 println!("\nπ Executor pattern example completed successfully!");
374 println!("π‘ Key advantages of ApiExecutor:");
375 println!(" β’ Ergonomic API: executor.execute(Operation, ¶meters)");
376 println!(" β’ Centralized context management with owned context");
377 println!(" β’ Consistent patterns across different API families");
378 println!(" β’ Easy context inspection and debugging");
379 println!(" β’ Efficient state sharing (cache, connections, etc.)");
380}Sourcepub fn execute<P, Op>(
&mut self,
_op: Op,
parameters: &P,
) -> Result<Op::Output, Op::Error>where
Op: ApiOperation<C, P>,
pub fn execute<P, Op>(
&mut self,
_op: Op,
parameters: &P,
) -> Result<Op::Output, Op::Error>where
Op: ApiOperation<C, P>,
Executes an API operation using this executorβs context.
Examples found in repository?
examples/executor_pattern.rs (lines 240-246)
213fn main() {
214 println!("π§ ApiThing Executor Pattern Example");
215 println!("====================================\n");
216
217 // Create an executor that manages the context for us
218 let mut executor = ApiExecutor::new(AppContext::new("production_db".to_string()));
219
220 println!("ποΈ Created ApiExecutor with context");
221 println!("π Connection: {}", executor.context().connection_pool());
222 println!(
223 "π’ Initial transaction count: {}\n",
224 executor.context().transaction_count()
225 );
226
227 // === User Operations ===
228 println!("π₯ USER OPERATIONS");
229 println!("==================");
230
231 // Create multiple users using the executor
232 let users = vec![
233 ("Alice Johnson", "alice@company.com"),
234 ("Bob Smith", "bob@company.com"),
235 ("Carol Davis", "carol@company.com"),
236 ];
237
238 let mut created_users = Vec::new();
239 for (name, email) in users {
240 match executor.execute(
241 CreateUser,
242 &CreateUserProps {
243 name: name.to_string(),
244 email: email.to_string(),
245 },
246 ) {
247 Ok(user) => {
248 println!("β
Created user: {} (ID: {})", user.name, user.id);
249 created_users.push(user);
250 }
251 Err(e) => {
252 println!("β Failed to create user {}: {:?}", name, e);
253 return;
254 }
255 }
256 }
257
258 println!(
259 "π’ Transaction count after user creation: {}\n",
260 executor.context().transaction_count()
261 );
262
263 // === Product Operations (Same Context) ===
264 println!("π¦ PRODUCT OPERATIONS");
265 println!("====================");
266
267 // Create products using the same executor/context
268 let products = vec![
269 ("Laptop Pro", 1299.99, "Electronics"),
270 ("Office Chair", 249.50, "Furniture"),
271 ("Coffee Mug", 12.99, "Kitchen"),
272 ];
273
274 let mut created_products = Vec::new();
275 for (name, price, category) in products {
276 match executor.execute(
277 CreateProduct,
278 &CreateProductProps {
279 name: name.to_string(),
280 price,
281 category: category.to_string(),
282 },
283 ) {
284 Ok(product) => {
285 println!(
286 "β
Created product: {} (ID: {}, Price: ${:.2})",
287 product.name, product.id, product.price
288 );
289 created_products.push(product);
290 }
291 Err(e) => {
292 println!("β Failed to create product {}: {:?}", name, e);
293 return;
294 }
295 }
296 }
297
298 println!(
299 "π’ Transaction count after product creation: {}\n",
300 executor.context().transaction_count()
301 );
302
303 // === Cross-Family Operations ===
304 println!("π CROSS-FAMILY LOOKUPS");
305 println!("=======================");
306
307 // Find users and products using the same context
308 // This demonstrates how the cache works across different API families
309
310 println!("π Looking up created entities...");
311
312 // Find first user
313 if let Some(user) = created_users.first() {
314 match executor.execute(FindUser, &FindUserProps { user_id: user.id }) {
315 Ok(found_user) => println!("π€ Found user: {} ({})", found_user.name, found_user.email),
316 Err(e) => println!("β Failed to find user: {:?}", e),
317 }
318 }
319
320 // Find first product
321 if let Some(product) = created_products.first() {
322 match executor.execute(
323 FindProduct,
324 &FindProductProps {
325 product_id: product.id,
326 },
327 ) {
328 Ok(found_product) => println!(
329 "π¦ Found product: {} (${:.2})",
330 found_product.name, found_product.price
331 ),
332 Err(e) => println!("β Failed to find product: {:?}", e),
333 }
334 }
335
336 // === Context Inspection ===
337 println!("\nπ CONTEXT INSPECTION");
338 println!("=====================");
339
340 let context = executor.context();
341 println!(
342 "π’ Final transaction count: {}",
343 context.transaction_count()
344 );
345 println!("πΎ Cache entries: {} items", context.cache().len());
346
347 // Show cache contents
348 println!("π Cached items:");
349 for (key, value) in context.cache().iter() {
350 // Truncate long values for display
351 let display_value = if value.len() > 50 {
352 format!("{}...", &value[..47])
353 } else {
354 value.clone()
355 };
356 println!(" β’ {}: {}", key, display_value);
357 }
358
359 // === Executor Benefits Demo ===
360 println!("\nπ‘ EXECUTOR BENEFITS");
361 println!("====================");
362
363 // Show how we can access the context for debugging or inspection
364 let final_context = executor.context();
365 println!("β
Centralized state management:");
366 println!(
367 " β’ {} total operations executed",
368 final_context.transaction_count()
369 );
370 println!(" β’ {} entities cached", final_context.cache().len());
371 println!(" β’ Single context shared across {} API families", 2);
372
373 println!("\nπ Executor pattern example completed successfully!");
374 println!("π‘ Key advantages of ApiExecutor:");
375 println!(" β’ Ergonomic API: executor.execute(Operation, ¶meters)");
376 println!(" β’ Centralized context management with owned context");
377 println!(" β’ Consistent patterns across different API families");
378 println!(" β’ Easy context inspection and debugging");
379 println!(" β’ Efficient state sharing (cache, connections, etc.)");
380}Sourcepub fn context(&self) -> &C
pub fn context(&self) -> &C
Returns an immutable reference to the executorβs context.
Examples found in repository?
examples/executor_pattern.rs (line 221)
213fn main() {
214 println!("π§ ApiThing Executor Pattern Example");
215 println!("====================================\n");
216
217 // Create an executor that manages the context for us
218 let mut executor = ApiExecutor::new(AppContext::new("production_db".to_string()));
219
220 println!("ποΈ Created ApiExecutor with context");
221 println!("π Connection: {}", executor.context().connection_pool());
222 println!(
223 "π’ Initial transaction count: {}\n",
224 executor.context().transaction_count()
225 );
226
227 // === User Operations ===
228 println!("π₯ USER OPERATIONS");
229 println!("==================");
230
231 // Create multiple users using the executor
232 let users = vec![
233 ("Alice Johnson", "alice@company.com"),
234 ("Bob Smith", "bob@company.com"),
235 ("Carol Davis", "carol@company.com"),
236 ];
237
238 let mut created_users = Vec::new();
239 for (name, email) in users {
240 match executor.execute(
241 CreateUser,
242 &CreateUserProps {
243 name: name.to_string(),
244 email: email.to_string(),
245 },
246 ) {
247 Ok(user) => {
248 println!("β
Created user: {} (ID: {})", user.name, user.id);
249 created_users.push(user);
250 }
251 Err(e) => {
252 println!("β Failed to create user {}: {:?}", name, e);
253 return;
254 }
255 }
256 }
257
258 println!(
259 "π’ Transaction count after user creation: {}\n",
260 executor.context().transaction_count()
261 );
262
263 // === Product Operations (Same Context) ===
264 println!("π¦ PRODUCT OPERATIONS");
265 println!("====================");
266
267 // Create products using the same executor/context
268 let products = vec![
269 ("Laptop Pro", 1299.99, "Electronics"),
270 ("Office Chair", 249.50, "Furniture"),
271 ("Coffee Mug", 12.99, "Kitchen"),
272 ];
273
274 let mut created_products = Vec::new();
275 for (name, price, category) in products {
276 match executor.execute(
277 CreateProduct,
278 &CreateProductProps {
279 name: name.to_string(),
280 price,
281 category: category.to_string(),
282 },
283 ) {
284 Ok(product) => {
285 println!(
286 "β
Created product: {} (ID: {}, Price: ${:.2})",
287 product.name, product.id, product.price
288 );
289 created_products.push(product);
290 }
291 Err(e) => {
292 println!("β Failed to create product {}: {:?}", name, e);
293 return;
294 }
295 }
296 }
297
298 println!(
299 "π’ Transaction count after product creation: {}\n",
300 executor.context().transaction_count()
301 );
302
303 // === Cross-Family Operations ===
304 println!("π CROSS-FAMILY LOOKUPS");
305 println!("=======================");
306
307 // Find users and products using the same context
308 // This demonstrates how the cache works across different API families
309
310 println!("π Looking up created entities...");
311
312 // Find first user
313 if let Some(user) = created_users.first() {
314 match executor.execute(FindUser, &FindUserProps { user_id: user.id }) {
315 Ok(found_user) => println!("π€ Found user: {} ({})", found_user.name, found_user.email),
316 Err(e) => println!("β Failed to find user: {:?}", e),
317 }
318 }
319
320 // Find first product
321 if let Some(product) = created_products.first() {
322 match executor.execute(
323 FindProduct,
324 &FindProductProps {
325 product_id: product.id,
326 },
327 ) {
328 Ok(found_product) => println!(
329 "π¦ Found product: {} (${:.2})",
330 found_product.name, found_product.price
331 ),
332 Err(e) => println!("β Failed to find product: {:?}", e),
333 }
334 }
335
336 // === Context Inspection ===
337 println!("\nπ CONTEXT INSPECTION");
338 println!("=====================");
339
340 let context = executor.context();
341 println!(
342 "π’ Final transaction count: {}",
343 context.transaction_count()
344 );
345 println!("πΎ Cache entries: {} items", context.cache().len());
346
347 // Show cache contents
348 println!("π Cached items:");
349 for (key, value) in context.cache().iter() {
350 // Truncate long values for display
351 let display_value = if value.len() > 50 {
352 format!("{}...", &value[..47])
353 } else {
354 value.clone()
355 };
356 println!(" β’ {}: {}", key, display_value);
357 }
358
359 // === Executor Benefits Demo ===
360 println!("\nπ‘ EXECUTOR BENEFITS");
361 println!("====================");
362
363 // Show how we can access the context for debugging or inspection
364 let final_context = executor.context();
365 println!("β
Centralized state management:");
366 println!(
367 " β’ {} total operations executed",
368 final_context.transaction_count()
369 );
370 println!(" β’ {} entities cached", final_context.cache().len());
371 println!(" β’ Single context shared across {} API families", 2);
372
373 println!("\nπ Executor pattern example completed successfully!");
374 println!("π‘ Key advantages of ApiExecutor:");
375 println!(" β’ Ergonomic API: executor.execute(Operation, ¶meters)");
376 println!(" β’ Centralized context management with owned context");
377 println!(" β’ Consistent patterns across different API families");
378 println!(" β’ Easy context inspection and debugging");
379 println!(" β’ Efficient state sharing (cache, connections, etc.)");
380}Sourcepub fn context_mut(&mut self) -> &mut C
pub fn context_mut(&mut self) -> &mut C
Returns a mutable reference to the executorβs context.
Trait ImplementationsΒ§
SourceΒ§impl<C: Clone> Clone for ApiExecutor<C>
impl<C: Clone> Clone for ApiExecutor<C>
SourceΒ§fn clone(&self) -> ApiExecutor<C>
fn clone(&self) -> ApiExecutor<C>
Returns a duplicate of the value. Read more
1.0.0 Β· SourceΒ§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
Performs copy-assignment from
source. Read moreAuto Trait ImplementationsΒ§
impl<C> Freeze for ApiExecutor<C>where
C: Freeze,
impl<C> RefUnwindSafe for ApiExecutor<C>where
C: RefUnwindSafe,
impl<C> Send for ApiExecutor<C>where
C: Send,
impl<C> Sync for ApiExecutor<C>where
C: Sync,
impl<C> Unpin for ApiExecutor<C>where
C: Unpin,
impl<C> UnwindSafe for ApiExecutor<C>where
C: UnwindSafe,
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