7.7 KiB
7.7 KiB
clap → match → volanie metód — kde robíš chybu
Tvoj problém nie je clap. Clap máš dobre. Tvoj problém je toto:
Sc::DajKnihuIsbn { cesta, isbn } => {
Kniznica::daj_knihu_podla_isbn(isbn); // ZLE
}
Tri chyby na jednom riadku:
- Nikde si nenačítal knižnicu zo súboru
- Voláš metódu ako statickú (
Kniznica::) namiesto na inštancii (kniznica.) - 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.
// 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ť.
// STATICKÁ metóda — nemá self, volaj cez Typ::
fn nacitaj_zo_suboru(cesta: &PathBuf) -> Option<Kniznica>
// 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ť.
// 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<Kniha, ()> — 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
// Čí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— nievypis_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.
// 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 &:
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ý
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.
// SIGNATÚRY:
// fn nacitaj_zo_suboru(cesta: &PathBuf) -> Option<Kontakty>
// fn uloz_do_suboru(&self, cesta: &PathBuf) -> bool
// fn pridaj(&mut self, kontakt: Kontakt) -> Result<(), ()>
// fn odstran(&mut self, meno: &str) -> Result<Kontakt, ()>
// 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ý:
let (mut) x = Typ::nacitaj_zo_suboru(&cesta).unwrap_or_default();let vysledok = x.metoda(&arg);match/if/forna výsledku- Ak
&mut selfmetóda →x.uloz_do_suboru(&cesta);