Подтвердить что ты не робот

Как разобрать файл JSON?

У меня есть это до сих пор в моей цели: проанализировать данные JSON в Rust:

extern crate rustc_serialize;
use rustc_serialize::json::Json;
use std::fs::File;
use std::io::copy;
use std::io::stdout;

fn main() {
    let mut file = File::open("text.json").unwrap();
    let mut stdout = stdout();
    let mut str = &copy(&mut file, &mut stdout).unwrap().to_string();
    let data = Json::from_str(str).unwrap();
}

и text.json есть

{
    "FirstName": "John",
    "LastName": "Doe",
    "Age": 43,
    "Address": {
        "Street": "Downing Street 10",
        "City": "London",
        "Country": "Great Britain"
    },
    "PhoneNumbers": [
        "+44 1234567",
        "+44 2345678"
    ]
}

Каким должен быть мой следующий шаг в его синтаксическом анализе? Моя основная цель - получить данные JSON, подобные этому, и проанализировать из него ключ, например Age.

4b9b3361

Ответ 1

Решено многими полезными членами сообщества Rust:

extern crate rustc_serialize;
use rustc_serialize::json::Json;
use std::fs::File;
use std::io::Read;

fn main() {
    let mut file = File::open("text.json").unwrap();
    let mut data = String::new();
    file.read_to_string(&mut data).unwrap();

    let json = Json::from_str(&data).unwrap();
    println!("{}", json.find_path(&["Address", "Street"]).unwrap());
}

Ответ 2

Serde является предпочтительным поставщиком сериализации JSON. Вы можете прочитать текст JSON из файла несколькими способами. Если у вас есть строка, используйте serde_json::from_str:

extern crate serde;
extern crate serde_json;

fn main() {
    let the_file = r#"{
        "FirstName": "John",
        "LastName": "Doe",
        "Age": 43,
        "Address": {
            "Street": "Downing Street 10",
            "City": "London",
            "Country": "Great Britain"
        },
        "PhoneNumbers": [
            "+44 1234567",
            "+44 2345678"
        ]
    }"#;

    let json: serde_json::Value =
        serde_json::from_str(the_file).expect("JSON was not well-formatted");
}

Вы даже можете использовать что-то вроде serde_json::from_reader для чтения непосредственно из открытого File.

Serde может использоваться для форматов, отличных от JSON, и может сериализоваться и десериализоваться в произвольную структуру вместо произвольной коллекции:

#[macro_use]
extern crate serde_derive;

#[derive(Debug, Deserialize)]
#[serde(rename_all = "PascalCase")]
struct Person {
    first_name: String,
    last_name: String,
    age: u8,
    address: Address,
    phone_numbers: Vec<String>,
}

#[derive(Debug, Deserialize)]
#[serde(rename_all = "PascalCase")]
struct Address {
    street: String,
    city: String,
    country: String,
}
let person: Person = serde_json::from_str(the_file).expect("JSON was not well-formatted");
println!("{:?}", person)

Проверьте веб-сайт Serde для более подробной информации.

Ответ 3

Существует краткий и полный пример того, как читать JSON из файла в документах serde_json::de::from_reader.

Вот короткий фрагмент для:

  • чтение файла
  • парсинг его содержимого как JSON
  • и извлечение поля с нужным ключом

Наслаждаться:

let file = fs::File::open("text.json")
    .expect("file should open read only");
let json: serde_json::Value = serde_json::from_reader(file)
    .expect("file should be proper JSON");
let first_name = json.get("FirstName")
    .expect("file should have FirstName key");

Ответ 4

Подтвердил принятый ответ (как он помогает), но просто добавил мой ответ, используя широко используемый ящик serde_json, на который ссылается @FrickeFresh

Предполагая, что ваш foo.json

{
    "name": "Jane",
    "age": 11
}

Реализация будет выглядеть примерно так

extern crate serde;
extern crate json_serde;
#[macro_use] extern crate json_derive;
use std::fs::File;
use std::io::Read;

#[derive(Serialize, Deserialize)]
struct Foo {
    name: String,
    age: u32,
}

fn main() {
   let mut file = File::open("foo.json").unwrap();
   let mut buff = String::new();
   file.read_to_string(&mut buff).unwrap();

   let foo: Foo = serde_json::from_str(&buff).unwrap();
   println!("Name: {}", foo.name);
}