use scripty::*;
fn main() -> Result<()> {
println!("🔗 Pipeline Fundamentals - scripty's Core Strength");
println!("=================================================\n");
println!("1. Basic pipelines:");
basic_pipes()?;
println!("\n2. Multi-stage command chains:");
multiple_pipes()?;
println!("\n3. Data processing pipelines:");
input_processing()?;
println!("\n4. Performance advantages:");
performance_demo()?;
println!("\n🎉 Pipeline fundamentals completed!");
println!("🚀 Next step:");
println!(" • Run 'cargo run --example 02_pipe_modes' for stderr/stdout control");
Ok(())
}
fn performance_demo() -> Result<()> {
println!(" Understanding scripty's performance advantages\n");
println!("🚀 Memory efficiency:");
println!(" scripty uses native pipes - data streams between commands");
println!(" without loading everything into memory at once.\n");
let sample_data = (1..=100)
.map(|i| format!("line {}", i))
.collect::<Vec<_>>()
.join("\n");
println!("📈 Streaming pipeline example:");
println!(" Processing 100 lines through multiple commands");
println!(" Command: generate_data | head -5 | wc -l");
let result = cmd!("head", "-5")
.pipe(cmd!("wc", "-l"))
.input(&sample_data)
.output()?;
println!(" Result: {} lines processed", result.trim());
println!(" 💡 The entire dataset never loads into memory simultaneously!");
println!("\n⚡ Pipeline vs individual commands:");
println!(" Pipeline: echo 'test data' | wc -c | tr -d ' '");
let pipeline_result = cmd!("echo", "test data")
.pipe(cmd!("wc", "-c"))
.pipe(cmd!("tr", "-d", " "))
.output()?;
println!(" Individual: Requires intermediate storage");
let step1 = cmd!("echo", "test data").output()?;
let step2 = cmd!("wc", "-c").input(&step1).output()?;
let individual_result = cmd!("tr", "-d", " ").input(&step2).output()?;
println!(
" Both approaches result: {} characters",
pipeline_result.trim()
);
println!(" (Individual result: {})", individual_result.trim());
println!(" But pipelines are more memory efficient! ⚡");
Ok(())
}
fn basic_pipes() -> Result<()> {
println!(" Two commands connected via pipe()\n");
println!("📝 Text transformation:");
println!(" Command: echo 'hello world' | tr '[:lower:]' '[:upper:]'");
cmd!("echo", "hello world")
.pipe(cmd!("tr", "[:lower:]", "[:upper:]"))
.run()?;
println!("\n🔄 String reversal:");
println!(" Command: echo 'scripty rocks' | rev");
cmd!("echo", "scripty rocks").pipe(cmd!("rev")).run()?;
println!("\n🔢 Word counting with output capture:");
println!(" Command: echo 'Hello beautiful scripty world' | wc -w");
let word_count = cmd!("echo", "Hello beautiful scripty world")
.pipe(cmd!("wc", "-w"))
.output()?;
println!(" Result: {} words", word_count.trim());
println!("\n📊 Character analysis:");
let char_analysis = cmd!("echo", "scripty").pipe(cmd!("wc", "-c")).output()?;
println!(
" 'scripty' has {} characters (including newline)",
char_analysis.trim()
);
Ok(())
}
fn multiple_pipes() -> Result<()> {
println!(" Chaining multiple commands for complex data processing\n");
println!("🔗 Three-stage text transformation:");
println!(" Command: echo 'Hello World' | tr '[:upper:]' '[:lower:]' | rev");
println!(" Process: Uppercase → Lowercase → Reverse");
cmd!("echo", "Hello World")
.pipe(cmd!("tr", "[:upper:]", "[:lower:]")) .pipe(cmd!("rev")) .run()?;
println!("\n🔄 Multi-stage data processing:");
println!(" Command: echo 'zebra,apple,cherry,banana' | tr ',' '\\n' | sort | tr '\\n' ','");
println!(" Process: CSV → Lines → Sort → CSV");
let result = cmd!("echo", "zebra,apple,cherry,banana")
.pipe(cmd!("tr", ",", "\n")) .pipe(cmd!("sort")) .pipe(cmd!("tr", "\n", ",")) .output()?;
println!(" Sorted result: {}", result.trim());
println!("\n📊 Text analysis pipeline:");
println!(" Analyzing word frequency in a sentence");
let analysis = cmd!(
"echo",
"the quick brown fox jumps over the lazy dog the end"
)
.pipe(cmd!("tr", " ", "\n")) .pipe(cmd!("sort")) .pipe(cmd!("uniq", "-c")) .pipe(cmd!("sort", "-nr")) .output()?;
println!(" Word frequency (most common first):");
for line in analysis.lines() {
if !line.trim().is_empty() {
println!(" {}", line.trim());
}
}
Ok(())
}
fn input_processing() -> Result<()> {
println!(" Processing custom input data through pipelines\n");
let fruit_data = "orange\napple\nbanana\napple\ncherry\nbanana\ndate\napple";
println!("📄 Sample dataset:");
println!(" {}", fruit_data.replace('\n', ", "));
println!("\n🔍 Deduplication and sorting:");
println!(" Command: sort | uniq");
let unique_sorted = cmd!("sort").pipe(cmd!("uniq")).input(fruit_data).output()?;
println!(" Unique items (sorted):");
for line in unique_sorted.lines() {
if !line.trim().is_empty() {
println!(" • {}", line.trim());
}
}
let total_count = cmd!("wc", "-l").input(fruit_data).output()?;
let unique_count = cmd!("sort")
.pipe(cmd!("uniq"))
.pipe(cmd!("wc", "-l"))
.input(fruit_data)
.output()?;
println!("\n📊 Statistics:");
println!(" Total items: {}", total_count.trim());
println!(" Unique items: {}", unique_count.trim());
println!("\n🏆 Frequency analysis:");
println!(" Command: sort | uniq -c | sort -nr | head -1");
let most_common = cmd!("sort")
.pipe(cmd!("uniq", "-c"))
.pipe(cmd!("sort", "-nr"))
.pipe(cmd!("head", "-1"))
.input(fruit_data)
.output()?;
println!(" Most common: {}", most_common.trim());
Ok(())
}