7
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Rust】serde_jsonあれこれ

Posted at

はじめに

rustお勉強2日目の初心者なので、温かい目で見守ってください。
間違いがあればコメントで指摘していただけると助かります。

serde_json - Rustdocs

jsonのキーに予約語に使われているとき〜

こんな感じのjsonがあるとする。

{
    "type": "hogehoge"
}

↓のような構造体に変換したい。
でも、typeって予約語。。。。

struct Fuga{
    type: String,
}

とりあえず書いてみるが、コンパイルは通らない
うん、知ってた。

src/main.rs
extern crate serde_json;

use serde_derive::Deserialize;

#[derive(Deserialize, Debug)]
struct Fuga {
    type: String,
}

fn main() {
    let json_str = r#"
    {
        "type": "hogehoge"
    }
    "#;
    let fuga: Fuga = serde_json::from_str(json_str).unwrap();
    println!("{:?}", fuga);
}

対処法その1

Raw identifiers を使用する。

実は、上記のコードを cargo run すると、こんなエラーが出てくる。

error: expected identifier, found keyword `type`
 --> src/main.rs:7:5
  |
7 |     type: String,
  |     ^^^^ expected identifier, found keyword
  |
help: you can escape reserved keywords to use them as identifiers
  |
7 |     r#type: String,
  |     ^^^^^^

help まで出してくれるなんて、優しい。
ということで、さきほどの構造体を↓のように書き換えて実行する。

struct Fuga {
    r#type: String,
}
$ cargo run
Fuga { type: "hogehoge" }

よしよし。

対処法その2

構造体のフィールドの名前を変えちゃう!

該当のフィールドの上に、これをつけるだけ。

#[serde(rename = "jsonのキー")]

Field attributes に詳しく書いてある。

ということで、構造体を↓のように書き換えて実行する。

struct Fuga {
    #[serde(rename = "type")]
    type_name: String,
}
$ cargo run
Fuga { type_name: "hogehoge" }

よしよし。

jsonのキーがキャメルやアッパーのとき〜

こんな感じのjsonがあるとする。

{
    "Type": "hogehoge"
}

構造体にするとしたら、こう??

struct Fuga{
    Type: String,
}

いいえ。

さきほどの Field attributes を使いましょう。

struct Fuga {
    #[serde(rename = "Type")]
    r#type: String,
}
src/main.rs
extern crate serde_json;

use serde_derive::Deserialize;

#[derive(Deserialize, Debug)]
struct Fuga {
    #[serde(rename = "Type")]
    r#type: String,
}

fn main() {
    let json_str = r#"
    {
        "Type": "hogehoge"
    }
    "#;
    let fuga: Fuga = serde_json::from_str(json_str).unwrap();
    println!("{:?}", fuga);
}
$ cargo run
Fuga { type: "hogehoge" }

よしよし。

ちなみに、キャメルでもできなくはない。
が、warning が出るのでよろしくない。

warning: structure field `Type` should have a snake case name
 --> src/main.rs:7:5
  |
7 |     Type: String,
  |     ^^^^
  |
  = note: `#[warn(non_snake_case)]` on by default
help: rename the identifier or convert it to a snake case raw identifier
  |
7 |     r#type: String,
  |     ^^^^^^

warning: 1 warning emitted

最後に

キャメル、アッパーのところ
もう一つ、やり方があった気がしたけど、忘れちゃった。。。
思い出したら追記します。

7
3
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?