やってみる

アウトプットすべく己を導くためのブログ。その試行錯誤すらたれ流す。

Rust自習(シリアライズ serde 3 chrono日時型変換)

 serdeにてchronoがもつ日時型と文字列を相互変換する。

成果物

参考

プロジェクト作成

$ cargo new serde_chrono --bin

Cargo.toml

[dependencies]
chrono = { version = "0.4", features = ["serde"] }
serde = { version = "1.0.97", features = ["derive"] }
serde_json = "1.0.40"
json5 = "0.2.5"

 実行してダウンロード&コンパイル。8分くらいかかる。

$ cargo run
...

test.json5

serde_chrono/test.json5

{
  /*
   * 複数行のコメント
   */
  // comments
  unquoted: 'and you can quote me on that',
  singleQuotes: 'I can use "double quotes" here',
  lineBreaks: "Look, Mom! \
No \\n's!",
  hexadecimal: 0xdecaf,
  leadingDecimalPoint: .8675309, andTrailing: 8675309.,
  positiveSign: +1,
  trailingComma: 'in objects', andIn: ['arrays',],
  "backwardsCompatible": "with JSON",
  inf: Infinity,
  ninf: -Infinity,
  nan: NaN,
  created: "2019-07-27T11:55:44+0900",
}

 末尾のcreatedに日付型DateTime<Local>を使う。

main.rs

serde_chrono/src/main.rs

use chrono::prelude::*;
use json5;
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize, Debug)]
struct J5 {
    unquoted: String,
    singleQuotes: String,
    lineBreaks: String,
    hexadecimal: i32,
    leadingDecimalPoint: f64,
    andTrailing: f64,
    positiveSign: i32,
    trailingComma: String,
    andIn: Vec<String>,
    backwardsCompatible: String,
    inf: f64,
    ninf: f64,
    nan: f64,
    created: DateTime<Local>,
}
fn main() {
    if let Ok(content) = std::fs::read_to_string("./test.json5") {
        let deserialized: J5 = json5::from_str(&content).unwrap();
        println!("deserialized = {:?}", deserialized);
    } else { println!("ファイル読み込みエラー。"); }
}

 成功!

deserialized = J5 { unquoted: "and you can quote me on that", singleQuotes: "I can use \"double quotes\" here", lineBreaks: "Look, Mom! No \\n\'s!", hexadecimal: 912559, leadingDecimalPoint: 0.8675309, andTrailing: 8675309.0, positiveSign: 1, trailingComma: "in objects", andIn: ["arrays"], backwardsCompatible: "with JSON", inf: inf, ninf: -inf, nan: NaN, created: 2019-07-27T11:55:44+09:00 }

失敗

 ちなみに、引用符で囲わないとエラーになる。

  created: 2019-07-27T11:55:44+0900
$ cargo run
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Message("  --> 18:12\n   |\n18 |   created: 2019-07-27T11:55:44+0900␊\n   |            ^---\n   |\n   = expected boolean, null, or string")', src/libcore/result.rs:999:5
note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace.

シリアライズしてファイル書込

use chrono::prelude::*;
use json5;
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize, Debug)]
struct J5 {
    unquoted: String,
    singleQuotes: String,
    lineBreaks: String,
    hexadecimal: i32,
    leadingDecimalPoint: f64,
    andTrailing: f64,
    positiveSign: i32,
    trailingComma: String,
    andIn: Vec<String>,
    backwardsCompatible: String,
    inf: f64,
    ninf: f64,
    nan: f64,
    created: DateTime<Local>,
}
fn main() {
    if let Ok(content) = std::fs::read_to_string("./test.json5") {
        let deserialized: J5 = json5::from_str(&content).unwrap();
        println!("deserialized = {:?}", deserialized);

        let serialized = json5::to_string(&deserialized).unwrap();
        println!("serialized = {}", serialized);
        std::fs::write("./test.write.json5", serialized);
    } else { println!("ファイル読み込みエラー。"); }
}

 実行。

deserialized = J5 { unquoted: "and you can quote me on that", singleQuotes: "I can use \"double quotes\" here", lineBreaks: "Look, Mom! No \\n\'s!", hexadecimal: 912559, leadingDecimalPoint: 0.8675309, andTrailing: 8675309.0, positiveSign: 1, trailingComma: "in objects", andIn: ["arrays"], backwardsCompatible: "with JSON", inf: inf, ninf: -inf, nan: NaN, created: 2019-07-27T11:55:44+09:00 }
serialized = {"unquoted":"and you can quote me on that","singleQuotes":"I can use \"double quotes\" here","lineBreaks":"Look, Mom! No \\n's!","hexadecimal":912559,"leadingDecimalPoint":0.8675309,"andTrailing":8675309,"positiveSign":1,"trailingComma":"in objects","andIn":["arrays"],"backwardsCompatible":"with JSON","inf":Infinity,"ninf":-Infinity,"nan":NaN,"created":"2019-07-27T11:55:44+09:00"}

 ファイル出力されていた。成功!

serde_chrono/test.write.json5

{"unquoted":"and you can quote me on that","singleQuotes":"I can use \"double quotes\" here","lineBreaks":"Look, Mom! No \\n's!","hexadecimal":912559,"leadingDecimalPoint":0.8675309,"andTrailing":8675309,"positiveSign":1,"trailingComma":"in objects","andIn":["arrays"],"backwardsCompatible":"with JSON","inf":Infinity,"ninf":-Infinity,"nan":NaN,"created":"2019-07-27T11:55:44+09:00"}

 でも、改行やスペースが無い。見やすくフォーマットしたい。

対象環境

$ uname -a
Linux raspberrypi 4.19.42-v7+ #1219 SMP Tue May 14 21:20:58 BST 2019 armv7l GNU/Linux

前回まで