use stillwater::{NonEmptyVec, Semigroup, Validation};
fn example_basic_creation() {
println!("\n=== Example 1: Basic Creation ===");
let nev1 = NonEmptyVec::new(1, vec![2, 3, 4]);
println!("new(1, vec![2, 3, 4]): {:?}", nev1);
println!(" head: {}, len: {}", nev1.head(), nev1.len());
let nev2 = NonEmptyVec::singleton(42);
println!("\nsingleton(42): {:?}", nev2);
println!(" head: {}, len: {}", nev2.head(), nev2.len());
let vec_with_items = vec![10, 20, 30];
match NonEmptyVec::from_vec(vec_with_items) {
Some(nev) => println!("\nfrom_vec(vec![10, 20, 30]): {:?}", nev),
None => println!("\nfrom_vec returned None (empty vec)"),
}
let empty_vec: Vec<i32> = vec![];
match NonEmptyVec::from_vec(empty_vec) {
Some(nev) => println!("from_vec(vec![]): {:?}", nev),
None => println!("from_vec(vec![]): None (as expected)"),
}
}
fn example_safe_operations() {
println!("\n=== Example 2: Safe Operations ===");
let nev = NonEmptyVec::new(10, vec![20, 30, 40, 50]);
println!("NonEmptyVec: {:?}", nev);
println!(" head: {}", nev.head());
println!(" last: {}", nev.last());
println!(" tail: {:?}", nev.tail());
println!(" len: {}", nev.len());
println!(" is_empty: {}", nev.is_empty());
println!(" nev[0]: {}", nev[0]);
println!(" nev[2]: {}", nev[2]);
let single = NonEmptyVec::singleton(99);
println!("\nSingleton: {:?}", single);
println!(" head: {}, last: {}", single.head(), single.last());
println!(" tail: {:?}", single.tail()); }
fn example_mutation() {
println!("\n=== Example 3: Mutation ===");
let mut nev = NonEmptyVec::singleton(1);
println!("Start: {:?}", nev);
nev.push(2);
nev.push(3);
nev.push(4);
println!("After pushes: {:?}", nev);
println!("\nPopping elements:");
while let Some(value) = nev.pop() {
println!(" Popped: {}, remaining: {:?}", value, nev);
}
println!("Final state: {:?} (can't pop head)", nev);
println!("Attempt to pop: {:?}", nev.pop()); }
fn example_functional_operations() {
println!("\n=== Example 4: Functional Operations ===");
let nev = NonEmptyVec::new(1, vec![2, 3, 4, 5]);
println!("Original: {:?}", nev);
let doubled = nev.clone().map(|x| x * 2);
println!("map(|x| x * 2): {:?}", doubled);
let strings = nev.clone().map(|x| format!("Item {}", x));
println!("map to strings: {:?}", strings);
let evens = nev.clone().filter(|x| x % 2 == 0);
println!("filter(even): {:?}", evens);
let all_positive = nev.clone().filter(|x| x > &0);
println!("filter(positive): {:?}", all_positive);
print!("iter sum: ");
let sum: i32 = nev.iter().sum();
println!("{}", sum);
let nev_copy = nev.clone();
let collected: Vec<_> = nev_copy.into_iter().collect();
println!("into_iter().collect(): {:?}", collected);
let vec = nev.into_vec();
println!("into_vec(): {:?}", vec);
}
fn example_semigroup() {
println!("\n=== Example 5: Semigroup (Concatenation) ===");
let nev1 = NonEmptyVec::new(1, vec![2, 3]);
let nev2 = NonEmptyVec::new(4, vec![5, 6]);
let nev3 = NonEmptyVec::singleton(7);
println!("nev1: {:?}", nev1);
println!("nev2: {:?}", nev2);
println!("nev3: {:?}", nev3);
let combined = nev1.combine(nev2);
println!("\nnev1.combine(nev2): {:?}", combined);
let all_combined = combined.combine(nev3);
println!("all combined: {:?}", all_combined);
let words = NonEmptyVec::new("Hello".to_string(), vec![]);
let more_words = NonEmptyVec::new("World".to_string(), vec!["!".to_string()]);
let sentence = words.combine(more_words);
println!("\nCombining strings: {:?}", sentence);
}
fn example_validation_integration() {
println!("\n=== Example 6: Validation Integration ===");
type ValidationError = String;
type ValidResult<T> = Validation<T, NonEmptyVec<ValidationError>>;
fn validate_email(email: &str) -> ValidResult<String> {
if email.contains('@') {
Validation::success(email.to_string())
} else {
Validation::fail("Email must contain @".to_string())
}
}
fn validate_age(age: i32) -> ValidResult<i32> {
if age >= 18 {
Validation::success(age)
} else {
Validation::fail(format!("Age must be >= 18, got {}", age))
}
}
fn validate_name(name: &str) -> ValidResult<String> {
if !name.is_empty() {
Validation::success(name.to_string())
} else {
Validation::fail("Name cannot be empty".to_string())
}
}
println!("Valid inputs:");
let result = validate_email("user@example.com")
.and(validate_age(25))
.and(validate_name("Alice"));
match result {
Validation::Success(((email, age), name)) => {
println!(" ✓ Success: {} is {} years old", name, age);
println!(" Email: {}", email);
}
Validation::Failure(errors) => {
println!(" ✗ Errors:");
for error in errors.iter() {
println!(" - {}", error);
}
}
}
println!("\nInvalid inputs:");
let result = validate_email("invalid-email")
.and(validate_age(15))
.and(validate_name(""));
match result {
Validation::Success(_) => println!(" ✓ Success"),
Validation::Failure(errors) => {
println!(" ✗ {} errors accumulated:", errors.len());
for (i, error) in errors.iter().enumerate() {
println!(" {}. {}", i + 1, error);
}
}
}
}
fn example_real_world_batch_processing() {
println!("\n=== Example 7: Real-world - Batch Processing ===");
#[derive(Debug, Clone)]
struct Task {
id: u32,
priority: u8,
}
fn process_batch(tasks: NonEmptyVec<Task>) -> (Task, Vec<Task>) {
let mut tasks_vec = tasks.into_vec();
tasks_vec.sort_by_key(|t| std::cmp::Reverse(t.priority));
let highest = tasks_vec.remove(0);
(highest, tasks_vec)
}
let batch = NonEmptyVec::new(
Task { id: 1, priority: 5 },
vec![
Task { id: 2, priority: 8 },
Task { id: 3, priority: 3 },
Task {
id: 4,
priority: 10,
},
],
);
println!("Processing batch with {} tasks", batch.len());
for task in batch.iter() {
println!(" Task #{}: priority {}", task.id, task.priority);
}
let (highest, rest) = process_batch(batch);
println!(
"\nHighest priority: Task #{} (priority {})",
highest.id, highest.priority
);
println!("Remaining {} tasks:", rest.len());
for task in &rest {
println!(" Task #{}: priority {}", task.id, task.priority);
}
}
fn example_aggregations() {
println!("\n=== Example 8: Safe Aggregations ===");
let numbers = NonEmptyVec::new(42, vec![17, 99, 8, 56]);
println!("Numbers: {:?}", numbers);
let min = numbers.iter().min().unwrap(); let max = numbers.iter().max().unwrap(); let sum: i32 = numbers.iter().sum();
let avg = sum as f64 / numbers.len() as f64;
println!(" min: {}", min);
println!(" max: {}", max);
println!(" sum: {}", sum);
println!(" avg: {:.2}", avg);
let factors = NonEmptyVec::new(2, vec![3, 5]);
let product: i32 = factors.iter().product();
println!("\nFactors: {:?}", factors);
println!(" product: {}", product);
}
fn main() {
println!("NonEmptyVec Examples");
println!("===================");
example_basic_creation();
example_safe_operations();
example_mutation();
example_functional_operations();
example_semigroup();
example_validation_integration();
example_real_world_batch_processing();
example_aggregations();
println!("\n=== All examples completed! ===");
}