Shanraq.org Shanraq.org
JSON пішімі
IT

Rust: алғашқы қадамнан жеке жоспарлау құралына дейін 51-сабақ (барлығы 60)

JSON пішімі

Сабақ 51. Тапсырмаларды JSON мәтініне айналдырып, қайта оқығанда тексеру.

Мәтін ИИ көмегімен аударылды.

Task құрылымын, сыртқы кітапханаларды және файл оқуды еске түсіріңіз. Мұнда дерек жадтағы мәтін түрінде болады; дискіге жазу келесі сабақта.

Таныс бейне және тірек сызба

Тапсырмалар тізімі атауы жазылған хатқалтадағы қағаздарға ұқсайды. JSON — өріс атаулары мен мәндерді ортақ ережемен жазатын мәтіндік пішім. Оны басқа бағдарлама оқи алады, бірақ хатқалтаның өзі ішіндегі деректің дұрыстығын дәлелдемейді. Тірек сызба: мәндер → JSON → JSON-ды оқу → мағынасын тексеру → дайын тапсырмалар. Осы жолды мәтінге қарамай айтып шығыңыз.

serde құрылымдарды дерекке және кері түрлендіреді; serde_json JSON-мен жұмыс істейді. Сериялау — мәнді мәтінге айналдыру, десериялау — мәтіннен мәнді қайта құрастыру. #[derive(Serialize, Deserialize)] құрылымға арналған қалыпты іске асыруды жасатады; #[serde(deny_unknown_fields)] танылмаған өрісті қабылдамайды. #[...] белгісі кейінгі жариялауға арналған компилятор нұсқауы. version — файл құрылымының нұсқа нөмірі; құрылым өзгерсе, ескі файлды жаңасы деп қабылдауға болмайды. next_id барлық бар ID-ден үлкен болуы керек. HashSet — қайталанбайтын мәндер жиыны; insert бұрын кездескен нөмір үшін false қайтарады. ? қатені шақырған жерге өткізеді. map_err кітапхана қатесін run үшін мәтінге айналдырады.

Іске қосып, талдаңыз

Жеке Cargo жобасын ашыңыз. Cargo.toml файлына төмендегі тәуелділіктерді жазыңыз, src/main.rs файлын алғашқы Rust үзіндісімен алмастырып, cargo run орындаңыз. Cargo кітапханаларды алғаш жинағанда жүктейді; Cargo.lock таңдалған нұсқаларды бекітеді. Үлгіде бір тапсырма бар. to_string JSON мәтінін жасайды, from_str қайта оқиды, ал validate JSON білмейтін мән ережелерін тексереді. Бұл үлгідегі өрістер реті құрылымдағы ретпен шығады; басқа бағдарлама оларды өзгеше орналастыра алады.

Cargo.toml файлына тәуелділіктерді қосыңыз (төмендегі жолдар [package] бөлімінен кейін):

Тәуелділік жазбасындағы version = "=1.0.228" ішкі = таңбасы дәл осы нұсқаны талап етеді, ал features = ["derive"] өрісі derive арқылы іске асыру жасау мүмкіндігін қосады; мұндағы тік жақшалар мүмкіндіктер тізімін білдіреді. Бұл — оқу үлгісіндегі нұсқаларды бекіту, олардың мәңгі өзекті болатынына уәде емес.

[dependencies]
serde = { version = "=1.0.228", features = ["derive"] }
serde_json = "=1.0.149"
use serde::{Deserialize, Serialize};
use std::collections::HashSet;

#[derive(Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
struct Task {
    id: u64,
    title: String,
    done: bool,
}

#[derive(Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
struct Organizer {
    version: u32,
    next_id: u64,
    tasks: Vec<Task>,
}

fn validate(data: &Organizer) -> Result<(), String> {
    if data.version != 1 || data.next_id == 0 {
        return Err(String::from("invalid version or next ID"));
    }
    let mut ids = HashSet::new();
    for task in &data.tasks {
        if task.id == 0
            || task.id >= data.next_id
            || task.title.trim().is_empty()
            || !ids.insert(task.id)
        {
            return Err(String::from("invalid task"));
        }
    }
    Ok(())
}

fn run() -> Result<(), String> {
    let source = Organizer {
        version: 1,
        next_id: 2,
        tasks: vec![Task {
            id: 1,
            title: String::from("Кітап сатып алу"),
            done: false,
        }],
    };
    let json = serde_json::to_string(&source).map_err(|error| error.to_string())?;
    let loaded: Organizer = serde_json::from_str(&json).map_err(|error| error.to_string())?;
    validate(&loaded)?;
    println!("{json}");
    println!("Қалпына келген тапсырма саны: {}", loaded.tasks.len());
    Ok(())
}

fn main() {
    if let Err(error) = run() {
        eprintln!("Қате: {error}");
        std::process::exit(1);
    }
}
{"version":1,"next_id":2,"tasks":[{"id":1,"title":"Кітап сатып алу","done":false}]}
Қалпына келген тапсырма саны: 1

Бетке қарамай жауап беріңіз

  1. JSON-ды оқу мен оның мағынасын тексерудің айырмасы қандай?
  2. Тізім бар болса, next_id не үшін қажет?
  3. Танылмаған өрісті неге қабылдамаған дұрыс?

Тапсырма

Міндетті. ID-і 2 болатын екінші тапсырманы қосып, next_id мәнін 3 етіңіз; қайта оқылған тапсырма санын шығарыңыз. Содан кейін оқылған екінші тапсырманың ID-ін 1-ге ауыстырып, тексеру қатені қайтаратынын көрсетіңіз. Алдымен екі нәтижені болжаңыз.

Жауаптар

Жауаптарды көрсету

Деректі to_string алдында өзгертіңіз. from_str соңында қайтадан Organizer аласыз. Қате нұсқа үшін loaded.tasks[1].id мәнін өзгертіп, тексеруді қайта шақырыңыз. validate(&bad).is_err() нәтижесін тексеріңіз.

use serde::{Deserialize, Serialize};
use std::collections::HashSet;

#[derive(Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
struct Task {
    id: u64,
    title: String,
    done: bool,
}

#[derive(Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
struct Organizer {
    version: u32,
    next_id: u64,
    tasks: Vec<Task>,
}

fn validate(data: &Organizer) -> Result<(), String> {
    if data.version != 1 || data.next_id == 0 {
        return Err(String::from("invalid version or next ID"));
    }
    let mut ids = HashSet::new();
    for task in &data.tasks {
        if task.id == 0
            || task.id >= data.next_id
            || task.title.trim().is_empty()
            || !ids.insert(task.id)
        {
            return Err(String::from("invalid task"));
        }
    }
    Ok(())
}

fn run() -> Result<(), String> {
    let source = Organizer {
        version: 1,
        next_id: 3,
        tasks: vec![
            Task {
                id: 1,
                title: String::from("Кітап сатып алу"),
                done: false,
            },
            Task {
                id: 2,
                title: String::from("Досқа қоңырау шалу"),
                done: false,
            },
        ],
    };
    let json = serde_json::to_string(&source).map_err(|error| error.to_string())?;
    let mut loaded: Organizer = serde_json::from_str(&json).map_err(|error| error.to_string())?;
    validate(&loaded)?;
    println!("{json}");
    println!("Қалпына келген тапсырма саны: {}", loaded.tasks.len());
    loaded.tasks[1].id = 1;
    println!(
        "Қайталанған ID қабылданбады: {}",
        validate(&loaded).is_err()
    );
    Ok(())
}

fn main() {
    if let Err(error) = run() {
        eprintln!("Қате: {error}");
        std::process::exit(1);
    }
}
{"version":1,"next_id":3,"tasks":[{"id":1,"title":"Кітап сатып алу","done":false},{"id":2,"title":"Досқа қоңырау шалу","done":false}]}
Қалпына келген тапсырма саны: 2
Қайталанған ID қабылданбады: true

Тексергеннен кейін

JSON жазылу ережесін, validate органайзер ережесін тексереді. Бүлінген деректі бос тізіммен алмастырмаңыз. 50-сабаққа оралу. Serde құжаттамасы.

Алдыңғы сабақ · Мазмұн

Мәтінде қате не теру қатесі кездессе, бізге айтыңыз

Пікірлер (0)

Әзірге пікір жоқ. Бірінші болыңыз.