# clap → match → volanie metód — kde robíš chybu Tvoj problém nie je clap. Clap máš dobre. Tvoj problém je toto: ```rust Sc::DajKnihuIsbn { cesta, isbn } => { Kniznica::daj_knihu_podla_isbn(isbn); // ZLE } ``` Tri chyby na jednom riadku: 1. Nikde si nenačítal knižnicu zo súboru 2. Voláš metódu ako statickú (`Kniznica::`) namiesto na inštancii (`kniznica.`) 3. Ignoruješ návratovú hodnotu --- ## Pravidlo 1: Najprv načítaj, potom volaj Metódy ako `daj_knihu_podla_isbn` sú `&self` metódy — potrebujú inštanciu. Tú musíš najprv vytvoriť z JSON súboru. ```rust // ZLE — Kniznica neexistuje, voláš na type Kniznica::daj_knihu_podla_isbn(isbn); // DOBRE — najprv načítaj, potom volaj na inštancii let kniznica = Kniznica::nacitaj_zo_suboru(&cesta).unwrap_or_default(); kniznica.daj_knihu_podla_isbn(&isbn); ``` --- ## Pravidlo 2: Statické vs inštančné metódy Pozri sa na signatúru metódy. To ti povie ako ju volať. ```rust // STATICKÁ metóda — nemá self, volaj cez Typ:: fn nacitaj_zo_suboru(cesta: &PathBuf) -> Option // Volanie: let kniznica = Kniznica::nacitaj_zo_suboru(&cesta); // &self metóda — len čítanie, volaj cez instancia. fn daj_knihu_podla_isbn(&self, isbn: &str) -> Option<&Kniha> // Volanie: let vysledok = kniznica.daj_knihu_podla_isbn(&isbn); // &mut self metóda — mení dáta, volaj cez mut instancia. fn pridaj_knihu(&mut self, kniha: Kniha) -> Result<(), ()> // Volanie: let mut kniznica = Kniznica::nacitaj_zo_suboru(&cesta).unwrap_or_default(); let vysledok = kniznica.pridaj_knihu(kniha); ``` Zhrnutie: | Signatúra | Čo potrebuješ | Volanie | |-----------|---------------|---------| | `fn nieco(cesta: &PathBuf)` — bez self | nič | `Kniznica::nieco(&cesta)` | | `fn nieco(&self, ...)` | `let kniznica = ...` | `kniznica.nieco(...)` | | `fn nieco(&mut self, ...)` | `let mut kniznica = ...` | `kniznica.nieco(...)` | --- ## Pravidlo 3: Spracuj návratovú hodnotu Každá metóda niečo vracia. Musíš s tým niečo urobiť. ```rust // Option<&Kniha> — buď existuje, alebo nie match kniznica.daj_knihu_podla_isbn(&isbn) { Some(kniha) => println!("{}", kniha), None => println!("Kniha nenájdená"), } // Vec<&Kniha> — môže byť prázdny let knihy = kniznica.daj_knihy_autora(&autor); if knihy.is_empty() { println!("Žiadne knihy"); } else { for kniha in &knihy { println!("{}", kniha); } } // Result — podarilo sa alebo nie match kniznica.odstran_knihu(&isbn) { Ok(kniha) => println!("Odstránená: {}", kniha), Err(()) => println!("Kniha nenájdená"), } ``` --- ## Pravidlo 4: Ak meníš dáta, ulož na konci ```rust // Čítacie metódy (&self) — NEUKLADAJ Sc::DajKnihuIsbn { cesta, isbn } => { let kniznica = Kniznica::nacitaj_zo_suboru(&cesta).unwrap_or_default(); // daj_knihu_podla_isbn je &self — len číta match kniznica.daj_knihu_podla_isbn(&isbn) { Some(kniha) => println!("{}", kniha), None => println!("Nenájdená"), } // ŽIADNE uloženie — nič sa nezmenilo } // Meniace metódy (&mut self) — ULOŽ! Sc::OdstranKnihu { cesta, isbn } => { let mut kniznica = Kniznica::nacitaj_zo_suboru(&cesta).unwrap_or_default(); // odstran_knihu je &mut self — mení dáta match kniznica.odstran_knihu(&isbn) { Ok(kniha) => { println!("Odstránená: {}", kniha); kniznica.uloz_do_suboru(&cesta); // ULOŽ ZMENY! } Err(()) => println!("Nenájdená"), } } ``` Keď uložiť: - `pridaj_knihu` — áno (pridávaš) - `odstran_knihu` — áno (mažeš) - `daj_knihu_podla_isbn` — nie (len čítaš) - `daj_knihy_autora` — nie - `vypis_vydavatelstva_a_pocet_knih` — nie --- ## Pravidlo 5: &isbn vs isbn — referencie v argumentoch Pozri sa čo metóda chce. Ak chce `&str`, daj referenciu na String. ```rust // Metóda chce: isbn: &str fn daj_knihu_podla_isbn(&self, isbn: &str) -> Option<&Kniha> // Ty máš: isbn: String (z clapu) // Volanie: kniznica.daj_knihu_podla_isbn(&isbn) // & premení String na &str ``` Vždy keď metóda berie `&str` a ty máš `String`, daj `&`: ```rust kniznica.daj_knihu_podla_isbn(&isbn); // String → &str kniznica.daj_knihy_autora(&autor); // String → &str kniznica.odstran_knihu(&isbn); // String → &str kniznica.daj_knihy_podla_stavu(stav); // Stav sa predáva priamo (nie referencia) ``` --- ## Tvoj kód opravený ```rust use clap::{Parser, Subcommand}; use std::path::PathBuf; use riesenie1::Kniznica; #[derive(Parser, Debug)] struct Args { #[command(subcommand)] cmd: Sc, } #[derive(Subcommand, Debug)] pub enum Sc { DajKnihuIsbn { cesta: PathBuf, isbn: String, }, DajKnihyAutora { cesta: PathBuf, autor: String, }, OdstranKnihu { cesta: PathBuf, isbn: String, }, VypisVydavatelstva { cesta: PathBuf, }, } fn main() { let args = Args::parse(); match args.cmd { Sc::DajKnihuIsbn { cesta, isbn } => { // 1. Načítaj let kniznica = Kniznica::nacitaj_zo_suboru(&cesta).unwrap_or_default(); // 2. Zavolaj na inštancii // 3. Spracuj výsledok match kniznica.daj_knihu_podla_isbn(&isbn) { Some(kniha) => println!("{}", kniha), None => println!("Kniha s ISBN {} nenájdená", isbn), } } Sc::DajKnihyAutora { cesta, autor } => { let kniznica = Kniznica::nacitaj_zo_suboru(&cesta).unwrap_or_default(); let knihy = kniznica.daj_knihy_autora(&autor); if knihy.is_empty() { println!("Žiadne knihy od autora {}", autor); } else { for kniha in &knihy { println!("{}", kniha); } } } Sc::OdstranKnihu { cesta, isbn } => { // mut! lebo odstran_knihu je &mut self let mut kniznica = Kniznica::nacitaj_zo_suboru(&cesta).unwrap_or_default(); match kniznica.odstran_knihu(&isbn) { Ok(kniha) => { println!("Odstránená: {}", kniha); kniznica.uloz_do_suboru(&cesta); // ULOŽ! } Err(()) => println!("Kniha s ISBN {} nenájdená", isbn), } } Sc::VypisVydavatelstva { cesta } => { let kniznica = Kniznica::nacitaj_zo_suboru(&cesta).unwrap_or_default(); // Táto metóda sama vypíše — len ju zavolaj kniznica.vypis_vydavatelstva_a_pocet_knih(); } } } ``` --- ## Cvičenie: Doplň match arms Dopíš chýbajúce časti. Signatúry metód sú v komentároch. ```rust // SIGNATÚRY: // fn nacitaj_zo_suboru(cesta: &PathBuf) -> Option // fn uloz_do_suboru(&self, cesta: &PathBuf) -> bool // fn pridaj(&mut self, kontakt: Kontakt) -> Result<(), ()> // fn odstran(&mut self, meno: &str) -> Result // fn hladaj(&self, meno: &str) -> Option<&Kontakt> // fn vsetky(&self) -> Vec<&Kontakt> match args.cmd { Sc::Pridaj { cesta, meno, telefon } => { // TODO: načítaj (mut!), vytvor Kontakt, pridaj, ulož ak ok } Sc::Odstran { cesta, meno } => { // TODO: načítaj (mut!), odstráň, vypíš výsledok, ulož ak ok } Sc::Hladaj { cesta, meno } => { // TODO: načítaj, hľadaj, vypíš Some/None } Sc::Vypis { cesta } => { // TODO: načítaj, zavolaj vsetky(), iteruj a vypíš } } ``` Skús to vyplniť sám. Ak nevieš, pozri na opravený kód vyššie — vzor je vždy rovnaký: 1. `let (mut) x = Typ::nacitaj_zo_suboru(&cesta).unwrap_or_default();` 2. `let vysledok = x.metoda(&arg);` 3. `match/if/for` na výsledku 4. Ak `&mut self` metóda → `x.uloz_do_suboru(&cesta);`