icu_provider_source/cldr_serde/
japanese.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
// This file is part of ICU4X. For terms of use, please see the file
// called LICENSE at the top level of the ICU4X source tree
// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).

use icu::calendar::provider::EraStartDate;
use serde::{de::Error, Deserialize, Deserializer};
use std::{borrow::Cow, collections::HashMap};

// cldr-core/supplemental/calendarData.json
#[derive(PartialEq, Debug, Deserialize)]
pub(crate) struct Resource {
    pub(crate) supplemental: Supplemental,
}

#[derive(PartialEq, Debug, Deserialize)]
pub(crate) struct Supplemental {
    #[serde(rename = "calendarData")]
    pub(crate) calendar_data: CalendarDatas,
}

#[derive(PartialEq, Debug, Deserialize)]
pub(crate) struct CalendarDatas {
    pub(crate) japanese: CalendarData,
}

#[derive(PartialEq, Debug, Deserialize)]
pub(crate) struct CalendarData {
    pub(crate) eras: HashMap<String, EraStart>,
}

#[derive(PartialEq, Debug, Deserialize)]
pub(crate) struct EraStart {
    #[serde(rename = "_start", deserialize_with = "parse_era_start_date")]
    pub(crate) start: Option<EraStartDate>,
}

fn parse_era_start_date<'de, D: Deserializer<'de>>(
    de: D,
) -> Result<Option<EraStartDate>, D::Error> {
    let s = Cow::<str>::deserialize(de)?;
    let mut s = &*s;
    let sign = if let Some(suffix) = s.strip_prefix('-') {
        s = suffix;
        -1
    } else {
        1
    };

    let mut split = s.split('-');
    let year = split
        .next()
        .ok_or(D::Error::custom("EraStartData format"))?
        .parse::<i32>()
        .map_err(|_| D::Error::custom("EraStartData format"))?
        * sign;
    let month = split
        .next()
        .ok_or(D::Error::custom("EraStartData format"))?
        .parse()
        .map_err(|_| D::Error::custom("EraStartData format"))?;
    let day = split
        .next()
        .ok_or(D::Error::custom("EraStartData format"))?
        .parse()
        .map_err(|_| D::Error::custom("EraStartData format"))?;

    Ok(Some(EraStartDate { year, month, day }))
}