mirror of
https://github.com/beerpiss/saekawa.git
synced 2024-11-23 23:00:58 +01:00
feat: parse userPlayDate as NaiveDateTime directly
This commit is contained in:
parent
ccb747cd33
commit
fc04a5ee01
@ -1,3 +1,5 @@
|
|||||||
|
Write-Output "Generating release for git SHA $(git rev-parse HEAD)"
|
||||||
|
|
||||||
cargo build --target i686-pc-windows-msvc --release
|
cargo build --target i686-pc-windows-msvc --release
|
||||||
|
|
||||||
if (!(Test-Path ./saekawa.pfx)) {
|
if (!(Test-Path ./saekawa.pfx)) {
|
||||||
|
@ -29,3 +29,43 @@ where
|
|||||||
BooleanishTypes::Number(n) => Ok(n > 0),
|
BooleanishTypes::Number(n) => Ok(n > 0),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mod serde_user_play_date {
|
||||||
|
use chrono::NaiveDateTime;
|
||||||
|
use serde::{ser, de};
|
||||||
|
|
||||||
|
const DT_FORMAT: &str = "%Y-%m-%d %H:%M:%S";
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct UserPlayDateVisitor;
|
||||||
|
|
||||||
|
pub fn serialize<S>(dt: &NaiveDateTime, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
S: ser::Serializer,
|
||||||
|
{
|
||||||
|
serializer.serialize_str(&dt.format(DT_FORMAT).to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deserialize<'de, D>(deserializer: D) -> Result<NaiveDateTime, D::Error>
|
||||||
|
where
|
||||||
|
D: de::Deserializer<'de>,
|
||||||
|
{
|
||||||
|
deserializer.deserialize_str(UserPlayDateVisitor)
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'de> de::Visitor<'de> for UserPlayDateVisitor {
|
||||||
|
type Value = NaiveDateTime;
|
||||||
|
|
||||||
|
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
write!(formatter, "a string in the format of \"{}\"", DT_FORMAT)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
|
||||||
|
where
|
||||||
|
E: de::Error,
|
||||||
|
{
|
||||||
|
NaiveDateTime::parse_from_str(v, DT_FORMAT)
|
||||||
|
.map_err(E::custom)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
|
use chrono::NaiveDateTime;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_aux::prelude::*;
|
use serde_aux::prelude::*;
|
||||||
|
|
||||||
use super::deserialize_bool;
|
use super::{deserialize_bool, serde_user_play_date};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
@ -46,15 +47,17 @@ pub struct UserDataEx {
|
|||||||
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct UserPlaylog {
|
pub struct UserPlaylog {
|
||||||
// This decides what `level` indices mean.
|
/// This decides what `level` indices mean.
|
||||||
// rom version 1.xx.yy: 0->4 for BASIC/ADVANCED/EXPERT/MASTER/WORLD'S END
|
/// rom version 1.xx.yy: 0->4 for BASIC/ADVANCED/EXPERT/MASTER/WORLD'S END
|
||||||
// rom version 2.xx.yy: 0->5 for BASIC/ADVANCED/EXPERT/MASTER/ULTIMA/WORLD'S END
|
/// rom version 2.xx.yy: 0->5 for BASIC/ADVANCED/EXPERT/MASTER/ULTIMA/WORLD'S END
|
||||||
pub rom_version: String,
|
pub rom_version: String,
|
||||||
|
|
||||||
pub music_id: String,
|
pub music_id: String,
|
||||||
|
|
||||||
// This is in UTC+9
|
/// The date and time the player set this score with, in the local time
|
||||||
pub user_play_date: String,
|
/// perceived by the game. On most setups this will be UTC+9.
|
||||||
|
#[serde(with = "serde_user_play_date")]
|
||||||
|
pub user_play_date: NaiveDateTime,
|
||||||
|
|
||||||
#[serde(deserialize_with = "deserialize_number_from_string")]
|
#[serde(deserialize_with = "deserialize_number_from_string")]
|
||||||
pub level: u32,
|
pub level: u32,
|
||||||
@ -90,6 +93,10 @@ pub struct UserPlaylog {
|
|||||||
#[serde(deserialize_with = "deserialize_bool")]
|
#[serde(deserialize_with = "deserialize_bool")]
|
||||||
pub is_full_combo: bool,
|
pub is_full_combo: bool,
|
||||||
|
|
||||||
|
/// In CHUNITHM SUN+ and beyond this is actually an integer, with different
|
||||||
|
/// indexes for different clear lamps, ranging from a normal CLEAR to a CATASTROPHY
|
||||||
|
/// (similar to EX HARD CLEAR). To keep things simple it's all smushed to a boolean,
|
||||||
|
/// since Tachi doesn't implement those clear lamps.
|
||||||
#[serde(deserialize_with = "deserialize_bool")]
|
#[serde(deserialize_with = "deserialize_bool")]
|
||||||
pub is_clear: bool,
|
pub is_clear: bool,
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
pub mod chuni;
|
pub mod chuni;
|
||||||
pub mod tachi;
|
pub mod tachi;
|
||||||
|
|
||||||
use chrono::{FixedOffset, NaiveDateTime, TimeZone};
|
use chrono::{FixedOffset, TimeZone};
|
||||||
use num_enum::TryFromPrimitiveError;
|
use num_enum::TryFromPrimitiveError;
|
||||||
use snafu::{ResultExt, Snafu};
|
use snafu::{ResultExt, Snafu};
|
||||||
|
|
||||||
@ -20,9 +20,6 @@ pub enum ScoreConversionError {
|
|||||||
InvalidDifficulty {
|
InvalidDifficulty {
|
||||||
source: TryFromPrimitiveError<Difficulty>,
|
source: TryFromPrimitiveError<Difficulty>,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[snafu(display("Invalid play date."))]
|
|
||||||
InvalidPlayDate { source: chrono::format::ParseError },
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UserPlaylog {
|
impl UserPlaylog {
|
||||||
@ -60,10 +57,8 @@ impl UserPlaylog {
|
|||||||
Difficulty::try_from(self.level).context(InvalidDifficultySnafu)?
|
Difficulty::try_from(self.level).context(InvalidDifficultySnafu)?
|
||||||
};
|
};
|
||||||
|
|
||||||
let datetime = NaiveDateTime::parse_from_str(&self.user_play_date, "%Y-%m-%d %H:%M:%S")
|
|
||||||
.context(InvalidPlayDateSnafu)?;
|
|
||||||
let jst_offset = FixedOffset::east_opt(9 * 3600).expect("chrono should parse JST timezone");
|
let jst_offset = FixedOffset::east_opt(9 * 3600).expect("chrono should parse JST timezone");
|
||||||
let jst_time = jst_offset.from_local_datetime(&datetime).unwrap();
|
let jst_time = jst_offset.from_local_datetime(&self.user_play_date).unwrap();
|
||||||
|
|
||||||
Ok(BatchManualScore {
|
Ok(BatchManualScore {
|
||||||
score: self.score,
|
score: self.score,
|
||||||
|
Loading…
Reference in New Issue
Block a user