CodeBlanks Logo Icon CodeBlanks

Reading commands

Read command-line arguments with std::env::args.

Reading commands

In a real CLI, commands come from the program arguments: cargo run -- ekle "Süt al". std::env::args() gives the program path as its first element:

let args: Vec<String> = std::env::args().collect();
match args.get(1).map(|s| s.as_str()) {
    Some("ekle") => { /* args[2] */ }
    Some("liste") => { /* ... */ }
    _ => println!("Kullanım: todo <ekle|liste|bitir>"),
}

In the exercise we'll give the commands in an array and split each command into a name and an argument with split_once(' ').

Matching commands

Commands without arguments, like "liste", have no space; with unwrap_or((k, "")) we take the whole text as the name and the argument as empty. Then a match on the name:

for k in komutlar {
    let (ad, arg) = k.split_once(' ').unwrap_or((k, ""));
    match ad {
        "ekle" => { liste.ekle(arg); }
        "bitir" => { /* arg.parse() */ }
        "liste" => liste.listele(),
        _ => println!("Bilinmeyen komut: {ad}"),
    }
}

Practice Command handler

Process the commands ["ekle Süt al", "ekle Kod yaz", "bitir 1", "liste", "sil 3"] in order. Run ekle, bitir (parse the id) and liste with the methods you support; for anything else print Bilinmeyen komut: AD.

Starter code

main.rs
struct Gorev {
    id: u32,
    metin: String,
    bitti: bool,
}

struct Liste {
    gorevler: Vec<Gorev>,
    sonraki_id: u32,
}

fn main() {
    // buraya yaz
}

Sample solution

main.rs
struct Gorev {
    id: u32,
    metin: String,
    bitti: bool,
}

struct Liste {
    gorevler: Vec<Gorev>,
    sonraki_id: u32,
}

impl Liste {
    fn ekle(&mut self, metin: &str) -> u32 {
        self.sonraki_id += 1;
        self.gorevler.push(Gorev {
            id: self.sonraki_id,
            metin: metin.to_string(),
            bitti: false,
        });
        self.sonraki_id
    }
    fn tamamla(&mut self, id: u32) -> bool {
        match self.gorevler.iter_mut().find(|g| g.id == id) {
            Some(g) => {
                g.bitti = true;
                true
            }
            None => false,
        }
    }
    fn listele(&self) {
        for g in &self.gorevler {
            let isaret = if g.bitti { "x" } else { " " };
            println!("[{}] {}: {}", isaret, g.id, g.metin);
        }
    }
}

fn main() {
    let mut liste = Liste {
        gorevler: Vec::new(),
        sonraki_id: 0,
    };
    let komutlar = ["ekle Süt al", "ekle Kod yaz", "bitir 1", "liste", "sil 3"];
    for k in komutlar {
        let (ad, arg) = k.split_once(' ').unwrap_or((k, ""));
        match ad {
            "ekle" => {
                liste.ekle(arg);
            }
            "bitir" => {
                let tamam = arg.parse().map(|id| liste.tamamla(id)).unwrap_or(false);
                if !tamam {
                    println!("Görev yok: {}", arg);
                }
            }
            "liste" => liste.listele(),
            _ => println!("Bilinmeyen komut: {}", ad),
        }
    }
}

Expected output

[x] 1: Süt al
[ ] 2: Kod yaz
Bilinmeyen komut: sil

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 What does <code>"bitir 1".split_once(' ')</code> return?

  • ("bitir", "1")
  • None
  • Some(("bitir", "1")) Correct answer
  • ["bitir", "1"]

Explanation: split_once splits at the first separator and returns a pair inside an Option; None if there is no separator.

2 Name and argument

Question
let (ad, arg) = k.____(' ').unwrap_or((k, ""));
Answer
let (ad, arg) = k.split_once(' ').unwrap_or((k, ""));

Explanation: split_once splits the text into two pieces at the first space.

3 Command and action

Term Meaning
ekle Süt al Adds a task
bitir 1 Marks number 1
liste Prints the list
sil 3 Unknown command

All lessons in Beginner