Skip to content
This repository was archived by the owner on Oct 12, 2022. It is now read-only.

Commit

Permalink
Release v1.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
Genbuchan committed Jul 18, 2022
1 parent 76e6ea9 commit 16dcce4
Show file tree
Hide file tree
Showing 9 changed files with 846 additions and 802 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "data-formats"
version = "0.1.0"
version = "1.0.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
Expand Down
20 changes: 10 additions & 10 deletions docs/code-structures.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,16 @@
│   └── ...
└──src // ソースコードが格納されています
   ├── lib.rs // ライブラリクレートして外部に公開するモジュールが指定されています
   ├── structs // 外部に公開される構造体が定義されています
   │  └── ...
   ├── structs.rs // structsディレクトリをモジュールとして扱うためのソースファイルです
├── tests // ソフトウェアテストのコードが定義されています
│ └── ...
├── tests.rs // testsディレクトリをモジュールとして扱うためのソースファイルです
├── utils // 共通利用することを想定した、ユーティリティ関数や定数が定義されています
│ └── ...
└── utils.rs
├── lib.rs // ライブラリクレートして外部に公開するモジュールが指定されています
├── structs // 外部に公開される構造体が定義されています
│  └── ...
├── structs.rs // structsディレクトリの内容をモジュールとして扱うためのソースファイルです
├── tests // ソフトウェアテストのコードが定義されています
│ └── ...
├── tests.rs // testsディレクトリの内容をモジュールとして扱うためのソースファイルです
├── utils // 共通利用することを想定した、ユーティリティ関数や定数が定義されています
│ └── ...
└── utils.rs // utilsディレクトリの内容をモジュールとして扱うためのソースファイルです
```

## ソースディレクトリの役割
Expand Down
1 change: 1 addition & 0 deletions src/structs.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod last_update;
pub mod news;
pub mod status;
pub mod summary;
223 changes: 100 additions & 123 deletions src/structs/last_update.rs
Original file line number Diff line number Diff line change
@@ -1,67 +1,46 @@
use std::{
fmt::{
Error,
Formatter
}
};
use crate::utils::formats::DATETIME_FORMAT;
use chrono::{DateTime, Local, TimeZone};
use serde::{
Deserialize,
Deserializer,
de::{
Error as DeserializationError,
MapAccess,
Visitor
},
Serialize,
Serializer,
ser::{
SerializeStruct
}
};
use chrono::{
Local,
TimeZone
de::{Error as DeserializationError, MapAccess, Visitor},
ser::SerializeStruct,
Deserialize, Deserializer, Serialize, Serializer,
};
use crate::utils::formats::FORMAT;
use std::fmt::{Error, Formatter};

/// シリアライズする際のフィールド名です。
const FIELDS: &'static [&'static str] = &["update_data"];

#[derive(Clone, Debug)]
/// LastUpdate構造体のフィールド名です。
enum LastUpdateField {
DateTime
DateTime,
}

/// データの最終更新日を格納します。
#[derive(Debug)]
#[derive(Clone, Debug)]
pub struct LastUpdate<Local: TimeZone> {
/// chronoクレートの`DateTime<Local>`型の値を格納します。
pub datetime: chrono::DateTime<Local>
/// chronoクレートの`DateTime<Local>`型の値を格納します。
pub datetime: DateTime<Local>,
}

/// シリアライズ処理の実装です。
impl Serialize for LastUpdate<Local> {

fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
// 構造体のシリアライズを開始する
let mut state = serializer.serialize_struct(
"LastUpdate", 1
).unwrap();
// datetimeフィールドをシリアライズする
state.serialize_field(
"last_update",
&format!(
"{}",
self.datetime.format(FORMAT).to_string()
)
).unwrap();
// ステートを終了し、結果を返却する
state.end()
}

fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
// 構造体のシリアライズを開始する
let mut state = serializer.serialize_struct("LastUpdate", 1).unwrap();
// datetimeフィールドをシリアライズする
state
.serialize_field(
"last_update",
&format!("{}", self.datetime.format(DATETIME_FORMAT).to_string()),
)
.unwrap();
// ステートを終了し、結果を返却する
state.end()
}
}

/// LastUpdateFieldのVisitorを定義します。
Expand All @@ -70,34 +49,30 @@ impl Serialize for LastUpdate<Local> {
struct LastUpdateFieldVisitor;

impl<'de> Visitor<'de> for LastUpdateFieldVisitor {

type Value = LastUpdateField;

fn expecting(&self, formatter: &mut Formatter) -> Result<(), Error> {
write!(formatter, "`last_update` not found")
}

fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: DeserializationError,
{
match value {
"last_update" => Ok(LastUpdateField::DateTime),
_ => Err(DeserializationError::unknown_field(value, FIELDS))
}
}

type Value = LastUpdateField;

fn expecting(&self, formatter: &mut Formatter) -> Result<(), Error> {
write!(formatter, "`last_update` not found")
}

fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: DeserializationError,
{
match value {
"last_update" => Ok(LastUpdateField::DateTime),
_ => Err(DeserializationError::unknown_field(value, FIELDS)),
}
}
}

impl<'de> Deserialize<'de> for LastUpdateField {

fn deserialize<D>(deserializer: D) -> Result<Self, <D as Deserializer<'de>>::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_identifier(LastUpdateFieldVisitor)
}

fn deserialize<D>(deserializer: D) -> Result<Self, <D as Deserializer<'de>>::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_identifier(LastUpdateFieldVisitor)
}
}

/// LastUpdateのVisitorを定義します。
Expand All @@ -106,57 +81,59 @@ impl<'de> Deserialize<'de> for LastUpdateField {
struct LastUpdateVisitor;

impl<'de> Visitor<'de> for LastUpdateVisitor {

// 変換する対象の構造体型を定義
type Value = LastUpdate<Local>;

fn expecting(&self, formatter: &mut Formatter) -> Result<(), Error> {
write!(formatter, "format is not correct.")
}

fn visit_map<M>(self, mut map: M) -> Result<Self::Value, <M as MapAccess<'de>>::Error>
where
M: MapAccess<'de>
{
let mut update_date = None;

// 連想配列のキーを取得し
while let Some(key) = map.next_key::<LastUpdateField>().unwrap() {
match key {
// DateTimeを取り出し
LastUpdateField::DateTime => {
// 既にupdate_dateに内容が含まれていないか判定
if update_date.is_some() {
return Err(DeserializationError::duplicate_field(FIELDS[0]));
}
// 日付と時刻をパースし、格納する
update_date = Some(
Local.datetime_from_str(&map.next_value::<String>().unwrap(), FORMAT)
.unwrap()
);
}
}
}

// update_dateの中身を取り出す
let update_date = update_date.ok_or_else(
// フィールドが不足していることを伝える
|| DeserializationError::missing_field(FIELDS[0])
)?;

// LastUpdateを返却
Ok(LastUpdate { datetime: update_date })
}

// 変換する対象の構造体型を定義
type Value = LastUpdate<Local>;

fn expecting(&self, formatter: &mut Formatter) -> Result<(), Error> {
write!(formatter, "format is not correct.")
}

fn visit_map<M>(self, mut map: M) -> Result<Self::Value, <M as MapAccess<'de>>::Error>
where
M: MapAccess<'de>,
{
let mut update_date = None;

// 連想配列のキーを取得し
while let Some(key) = map.next_key::<LastUpdateField>().unwrap() {
match key {
// DateTimeを取り出し
LastUpdateField::DateTime => {
// 既にupdate_dateに内容が含まれていないか判定
if update_date.is_some() {
return Err(DeserializationError::duplicate_field(FIELDS[0]));
}
// 日付と時刻をパースし、格納する
update_date = Some(
Local
.datetime_from_str(
&map.next_value::<String>().unwrap(),
DATETIME_FORMAT,
)
.unwrap(),
);
}
}
}

// update_dateの中身を取り出す
let update_date = update_date.ok_or_else(
// フィールドが不足していることを伝える
|| DeserializationError::missing_field(FIELDS[0]),
)?;

// LastUpdateを返却
Ok(LastUpdate {
datetime: update_date,
})
}
}

impl<'de> Deserialize<'de> for LastUpdate<Local> {

fn deserialize<D>(deserializer: D) -> Result<Self, <D as Deserializer<'de>>::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_struct("LastUpdate", FIELDS, LastUpdateVisitor)
}

fn deserialize<D>(deserializer: D) -> Result<Self, <D as Deserializer<'de>>::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_struct("LastUpdate", FIELDS, LastUpdateVisitor)
}
}
Loading

0 comments on commit 16dcce4

Please sign in to comment.