Cél és előfeltétel
Egy parancssori eszköznek már az induláskor értenie kell, mit kér a hívó. Az argumentumok a program neve után megadott külön értékek, nem egyetlen tetszőlegesen szétdarabolandó mondat. Ebben a leckében egy fájlútvonalat fogadó eszköz hívási szabályát írod le. A program még nem olvassa a fájlt: először az indulási szerződést tesszük ellenőrizhetővé.
Előfeltétel a könyvtári katalógus miniprojektje, vagy azzal egyenértékű függvény-, enum- és kölcsönzési tudás. A teljes edition 2024 főprogramok itt a feldolgozót ellenőrző példák: maguk hozzák létre az argumentumlistát, ezért nem várnak valódi terminálbemenetre. Ezt ne keverd össze egy már telepített, minden környezetben kész végfelhasználói eszközzel.
Mit ad át a shell?
A shell általában még a program indulása előtt végzi el a saját idézőjel- és kifejezéskezelését. Egy szóközt tartalmazó fájlnevet ezért a használt shell szabályai szerint kell egy argumentumként megadni. A programnak érkező értéket nem szabad utólag minden szóköznél újra szétszedni, mert akkor az érvényes fájlnév több téves mezőre bomlana. A példáinkban a szóközös útvonal egyetlen elem marad.
A standard könyvtár argumentumiterátorának első eleme rendszerint a program hívási neve; ez nem az első felhasználói fájlútvonal. A tényleges belépési pont ezért külön kezeli vagy kihagyja az első elemet, mielőtt a feldolgozót hívja. A mostani függvények szerződése már csak a felhasználói argumentumokat tartalmazó listát fogadja. Ezt az egyezséget minden feladatban megtartjuk.
Használható hibajelzés és súgó
A használati útmutató mondja meg az eszköz nevét, az elvárt argumentumot és a súgó elérését. Ne csak annyi álljon benne, hogy hibás bemenet: ebből a hívó nem tudja meg, hogyan javítson. A súgókérés és a hibás hívás külön eset. A súgó megjelenítése szándékos, sikeres művelet lehet, a hiányzó kötelező bemenet viszont elutasítást jelent.
A feldolgozási eredményt Result típus jelzi: az Ok sikeres értéket, az Err hibát hordoz. Most rövid, rögzített hibaüzeneteket használunk; a részletesebb hibamodellel később foglalkozunk. A hiba tehát nem egy üres fájlnévbe rejtett jel. Így az érvényes bemenet és az elutasítás a típusban is külön marad, nem csupán egy megjegyzésben.
Útvonal és szöveg különbözhet
A String UTF-8 szöveget tárol, de az operációs rendszer útvonalai nem minden platformon írhatók le érvényes Unicode szövegként. Az args ezért nem minden argumentumhoz ideális; az args_os operációs rendszer szerinti szövegeket ad. Fájlútvonalhoz az OsString és a PathBuf segít megőrizni az eredeti alakot anélkül, hogy veszteséges megjelenítésből építenéd vissza az adatot.
Ez nem jelenti azt, hogy az útvonal biztosan létezik vagy olvasható. A hívás feldolgozása csak azt állapítja meg, hogy a szerződés szerint egyetlen nem üres érték érkezett. A fájl tényleges megnyitása külön művelet, külön hibával. Az elválasztás azért hasznos, mert a hiányzó argumentum teszteléséhez nem kell fájlrendszert készíteni vagy jogosultságokat módosítani.
1. feladat: segítség, amelyből hívás írható
Készíts rövid használati útmutatót a naplo nevű eszközhöz. Tartalmazza a kötelező FAJL helyét és a --help kapcsolót. Ellenőrizd a két fontos részlet jelenlétét és a szöveg sorvégi lezárását. A helyettesítő szó legyen világosan általános jelölés, ne egy létező fájl kötelező neve.
Megoldás
fn hasznalat() -> &'static str {
"Használat: naplo FAJL\nSúgó: naplo --help\n"
}
fn main() {
let szoveg = hasznalat();
assert!(szoveg.contains("naplo FAJL"));
assert!(szoveg.contains("naplo --help"));
assert!(szoveg.ends_with('\n'));
}
A használati szövegben a sorvége tudatos választás. A következő leckében különválasztjuk, hogy a sikeres súgó és a hibamagyarázat melyik kimeneti csatornára kerüljön.
2. feladat: pontosan egy felhasználói argumentum
Írj függvényt, amely pontosan egy nem üres String argumentumot fogad el, és saját String eredményt ad vissza. A szóközöket ne vágd le, mert az útvonal valódi részei lehetnek. Ellenőrizd a hiányt, a többletet, az üres értéket és a szóközös fájlnevet. Itt még kifejezetten UTF-8 példákat használunk.
Megoldás
fn fajlnev(args: &[String]) -> Result<String, &'static str> {
if args.len() != 1 { return Err("Pontosan egy fájlútvonal kell."); }
if args[0].is_empty() { return Err("Az útvonal nem lehet üres."); }
Ok(args[0].clone())
}
fn main() {
assert_eq!(fajlnev(&[String::from("napi naplo.txt")]), Ok(String::from("napi naplo.txt")));
assert!(fajlnev(&[]).is_err());
assert!(fajlnev(&[String::new()]).is_err());
assert!(fajlnev(&[String::from("a"), String::from("b")]).is_err());
}
A másolat itt azt biztosítja, hogy a feldolgozás eredménye önállóan tárolható legyen. A sikeres fájlnév nem arra tett ígéret, hogy a fájl megnyitható.
3. feladat: operációs rendszer szerinti útvonal
A feldolgozót alakítsd OsString listát fogadó függvénnyé. A --help egyetlen argumentumként súgót jelentsen, minden más egyetlen nem üres argumentum fájlútvonalat. Két argumentum még akkor is hiba, ha az első súgókapcsoló. A típussal fejezd ki a sikeres hívás két lehetséges esetét, és mindkettőt ellenőrizd.
Megoldás
use std::ffi::OsString;
use std::path::PathBuf;
#[derive(Debug, PartialEq, Eq)]
enum Hivas { Sugo, Fajl(PathBuf) }
fn ertelmez(args: &[OsString]) -> Result<Hivas, &'static str> {
if args.len() != 1 { return Err("Egy argumentum szükséges."); }
if args[0] == "--help" { return Ok(Hivas::Sugo); }
if args[0].is_empty() { return Err("Üres útvonal."); }
Ok(Hivas::Fajl(PathBuf::from(&args[0])))
}
fn main() {
assert_eq!(ertelmez(&[OsString::from("--help")]), Ok(Hivas::Sugo));
assert_eq!(ertelmez(&[OsString::from("napi naplo.txt")]), Ok(Hivas::Fajl(PathBuf::from("napi naplo.txt"))));
assert!(ertelmez(&[]).is_err());
assert!(ertelmez(&[OsString::from("--help"), OsString::from("x")]).is_err());
}
A feldolgozónak már nincs szüksége útvonalból kényszerített String készítésére. A tényleges argumentumgyűjtés később külön, rövid belépési rétegként illeszthető ehhez a függvényhez.
Elfogadási feltételek
- A használati útmutató a kötelező fájlargumentumot és a súgó hívását is megmutatja.
- A feldolgozó a hiányt, többletet és üres értéket elutasítja, a szóközös fájlnevet változatlanul megőrzi.
- A súgó külön eset, és az OsString alapú útvonal nem jár veszteséges szövegátalakítással.
Továbblépés
A hívás szabálya már tesztelhető. A standard bemenet és kimenet leckében a parancssori eszköz másik szerződését rendezed: honnan érkezik adat, és hová kerül az eredmény vagy a hibamagyarázat.