| Crates.io | sugars_async_task |
| lib.rs | sugars_async_task |
| version | 0.5.4 |
| created_at | 2025-07-17 19:14:29.367886+00 |
| updated_at | 2025-10-27 03:33:11.867226+00 |
| description | Async task utilities and abstractions for the cyrup-sugars ecosystem |
| homepage | https://github.com/cyrup-ai/cyrup-sugars |
| repository | https://github.com/cyrup-ai/cyrup-sugars |
| max_upload_size | |
| id | 1757965 |
| size | 28,954 |

Syntactic sugar utilities for Rust - collections, async patterns, and macros.
collections - Collection types: ZeroOneOrMany, OneOrMany, ByteSizeasync - Async utilities: AsyncTask and AsyncStreammacros - Collection and async macrosarray-tuples - Array tuple syntax for collectionsbuilders - Builder traits: MessageChunk, ChunkHandlergix-interop - Git object hash tablesThe array-tuples feature enables intuitive array tuple syntax in builder patterns:
let builder = FluentAi::agent_role("example")
.additional_params([("beta", "true"), ("debug", "false")])
.metadata([("key", "val"), ("foo", "bar")])
.tools((
Tool::<Perplexity>::new([("citations", "true"), ("format", "json")]),
));
Implementation Pattern:
/// Set additional parameters with array tuple syntax
pub fn additional_params<T>(mut self, params: T) -> Self
where
T: IntoHashMap
{
let config_map = params.into_hashmap();
let mut map = HashMap::new();
for (k, v) in config_map {
map.insert(k.to_string(), Value::String(v.to_string()));
}
self.additional_params = Some(map);
self
}
Usage: .additional_params([("beta", "true"), ("debug", "false")])
The array tuple syntax [("key", "value")] works seamlessly with the IntoHashMap trait, providing a clean and intuitive API for developers.
π For complete implementation details, see the Array Tuple Syntax Implementation Guide
The async feature provides concrete async types that avoid boxed futures:
use sugars_async_task::AsyncTask;
use sugars_collections::ZeroOneOrMany;
// Single receiver
let task = AsyncTask::new(ZeroOneOrMany::one(rx));
// Multiple receivers (first result wins)
let task = AsyncTask::new(ZeroOneOrMany::many(vec![rx1, rx2, rx3]));
// From future
let task = AsyncTask::from_future(some_async_operation());
let result = task.await;
AsyncTask supports single and multiple receivers using the ZeroOneOrMany pattern, enabling race conditions, fallback patterns, and load balancing.
π For complete usage examples, see the AsyncTask Usage Guide
The collections feature provides memory-efficient collection types for different scenarios:
use sugars_collections::{OneOrMany, ZeroOneOrMany};
// OneOrMany: Non-empty collections (guaranteed at least one element)
let servers = OneOrMany::many(vec!["server1", "server2"]).unwrap();
let primary = servers.first(); // Always exists
// ZeroOneOrMany: Flexible collections (zero allocations for None/One)
let middleware = ZeroOneOrMany::none();
let middleware = middleware.with_pushed("auth");
let middleware = middleware.with_pushed("cors");
match middleware {
ZeroOneOrMany::None => println!("No middleware"),
ZeroOneOrMany::One(mw) => println!("Single middleware: {}", mw),
ZeroOneOrMany::Many(mws) => println!("Multiple middleware: {:?}", mws),
}
Both types support JSON serialization, builder patterns, and zero-allocation optimizations for small collections.
π For complete guides, see OneOrMany Guide and ZeroOneOrMany Guide
The builders feature provides traits for message chunk handling:
MessageChunk - Trait for types that can represent both success and error statesChunkHandler<T, E> - Handles streaming Result<T, E> by unwrapping to TThese traits enable consistent error handling patterns across builders with a single on_chunk method that handles both success and error cases.
π For complete implementation guide, see the ChunkHandler Pattern Guide - Step-by-step instructions for implementing the full pattern from scratch.
Add this to your Cargo.toml:
[dependencies]
cyrup_sugars = "0.1.0"
Or with specific features:
[dependencies]
cyrup_sugars = { version = "0.1", features = ["array-tuples"] }
let stream = FluentAi::agent_role("rusty-squire")
.completion_provider(Mistral::MagistralSmall)
.temperature(1.0)
.max_tokens(8000)
.system_prompt("Act as a Rust developers 'right hand man'.
You possess deep expertise in using tools to research rust, cargo doc and github libraries.
You are a patient and thoughtful software artisan; a master of sequential thinking and step-by-step reasoning.
You excel in compilation triage ...
...
...
Today is {{ date }}
~ Be Useful, Not Thorough")
.context( // trait Context
Context<File>::of("/home/kloudsamurai/ai_docs/mistral_agents.pdf"),
Context<Files>::glob("/home/kloudsamurai/cyrup-ai/**/*.{md,txt}"),
Context<Directory>::of("/home/kloudsamurai/cyrup-ai/agent-role/ambient-rust"),
Context<Github>::glob("/home/kloudsamurai/cyrup-ai/**/*.{rs,md}")
)
.mcp_server<Stdio>::bin("/user/local/bin/sweetmcp").init("cargo run -- --stdio")
.tools( // trait Tool
Tool<Perplexity>::new([
("citations", "true"), ("format", "json")
]),
Tool::named("cargo").bin("~/.cargo/bin").description("cargo --help".exec_to_text())
) // ZeroOneOrMany `Tool` || `McpTool` || NamedTool (WASM)
.additional_params([("beta", "true"), ("debug", "false")])
.memory(Library::named("obsidian_vault"))
.metadata([("key", "val"), ("foo", "bar")])
.on_tool_result(|results| {
// do stuff
})
.on_conversation_turn(|conversation, agent| {
log.info("Agent: " + conversation.last().message())
agent.chat(process_turn()) // your custom logic
})
.on_chunk(|result| match result { // Handle Result<T, E> unwrapping
Ok(chunk) => {
println!("{}", chunk);
chunk
},
Err(e) => ConversationChunk::bad_chunk(e) // Convert error to bad chunk
})
.into_agent() // Agent Now
.conversation_history(MessageRole::User => "What time is it in Paris, France",
MessageRole::System => "The USER is inquiring about the time in Paris, France. Based on their IP address, I see they are currently in Las Vegas, Nevada, USA. The current local time is 16:45",
MessageRole::Assistant => "Itβs 1:45 AM CEST on July 7, 2025, in Paris, France. Thatβs 9 hours ahead of your current time in Las Vegas.")
.chat("Hello")? // AsyncStream<MessageChunk
.collect();
## Working Examples
### Message Chunk Handling
The `builders` feature provides powerful traits for handling streaming message chunks:
```rust
use cyrup_sugars::prelude::*;
use sugars_llm::*;
// MessageChunk trait - implemented by chunk types
pub trait MessageChunk: Sized {
fn bad_chunk(error: String) -> Self; // Create error chunk
fn error(&self) -> Option<&str>; // Get error if present
fn is_error(&self) -> bool; // Check if error chunk
}
// ChunkHandler trait - processes Result<T, E> streams
let builder = builder
.on_chunk(|result| match result {
Ok(chunk) => chunk,
Err(e) => ConversationChunk::bad_chunk(e)
});
// All these patterns work with array tuple syntax:
Tool::<Perplexity>::new([("citations", "true")])
.additional_params([("beta", "true"), ("debug", "false")])
.metadata([("key", "val"), ("foo", "bar")])
# Array tuple syntax with on_chunk method
cd examples/array_tuple_syntax && cargo run
# Async task pipeline
cd examples/async_task_example && cargo run
# Collection types
cd examples/one_or_many_example && cargo run
cd examples/zero_one_or_many_example && cargo run
Run tests with full coverage:
# Run all tests
cargo test --all-features
# Generate coverage report
cargo tarpaulin --all-features --out Html
Generate and view documentation:
cargo doc --all-features --open
Run performance benchmarks:
cargo bench --all-features
Contributions are welcome! Please ensure:
cargo test --all-featurescargo fmtcargo clippy --all-features -- -D warningscargo doc --all-featurescargo run --example <name> --features <features>Licensed under either of
at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.