clap2
This commit is contained in:
268
priprava/rust_priprava11.md
Normal file
268
priprava/rust_priprava11.md
Normal file
@@ -0,0 +1,268 @@
|
||||
# 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<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ť.
|
||||
|
||||
```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<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
|
||||
|
||||
```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<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ý:
|
||||
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);`
|
||||
Reference in New Issue
Block a user