feat: support dxratingnet format
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
use crate::{
|
||||
helper::MUSIC_DB,
|
||||
title::model::get_user_rating_api::{
|
||||
MusicRating, UserRating,
|
||||
dxrating::{DxCalculatedEntries, DxLevelName, DxMusicRecord, DxSheetId},
|
||||
},
|
||||
};
|
||||
|
||||
impl DxCalculatedEntries {
|
||||
pub fn from_user_rating_lossy(rating: &UserRating) -> DxCalculatedEntries {
|
||||
let b35 = rating
|
||||
.rating_list
|
||||
.iter()
|
||||
.map(DxMusicRecord::try_from)
|
||||
.flatten()
|
||||
.collect();
|
||||
let b15 = rating
|
||||
.new_rating_list
|
||||
.iter()
|
||||
.map(DxMusicRecord::try_from)
|
||||
.flatten()
|
||||
.collect();
|
||||
|
||||
DxCalculatedEntries { b35, b15 }
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<u32> for DxLevelName {
|
||||
type Error = ConversionError;
|
||||
|
||||
fn try_from(level: u32) -> Result<Self, Self::Error> {
|
||||
Self::from_repr(level).ok_or(ConversionError::UnknownDifficulty { level })
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<&MusicRating> for DxMusicRecord {
|
||||
type Error = ConversionError;
|
||||
|
||||
fn try_from(value: &MusicRating) -> Result<Self, Self::Error> {
|
||||
let music_title = MUSIC_DB
|
||||
.as_ref()
|
||||
.and_then(|db| db.get(&value.music_id))
|
||||
.map(|info| info.name.clone())
|
||||
.ok_or(ConversionError::MusicNotInDB)?;
|
||||
|
||||
Ok(Self {
|
||||
sheet_id: DxSheetId {
|
||||
music_title,
|
||||
level: DxLevelName::try_from(value.level)?,
|
||||
dx_version: value.music_id >= 1000,
|
||||
},
|
||||
achievement_rate: (value.achievement as f64) / 10000.0,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, snafu::Snafu)]
|
||||
pub enum ConversionError {
|
||||
#[snafu(display("Music was not found in database"))]
|
||||
MusicNotInDB,
|
||||
|
||||
#[snafu(display("Utage difficulty was disallowed"))]
|
||||
UtageDifficulty,
|
||||
|
||||
#[snafu(display("Unknown difficulty: {level}"))]
|
||||
UnknownDifficulty { level: u32 },
|
||||
}
|
||||
95
sdgb-api/src/title/model/get_user_rating_api/dxrating/mod.rs
Normal file
95
sdgb-api/src/title/model/get_user_rating_api/dxrating/mod.rs
Normal file
@@ -0,0 +1,95 @@
|
||||
use serde::Serialize;
|
||||
|
||||
/// Full payload for image generate api
|
||||
#[derive(Debug, Clone, PartialEq, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct DxRatingNet {
|
||||
pub calculated_entries: DxCalculatedEntries,
|
||||
|
||||
pub version: DataVersion,
|
||||
/// use `_generic`
|
||||
pub region: &'static str,
|
||||
}
|
||||
|
||||
/// Export/Import format
|
||||
#[derive(Debug, Clone, PartialEq, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct DxCalculatedEntries {
|
||||
pub b35: Vec<DxMusicRecord>,
|
||||
pub b15: Vec<DxMusicRecord>,
|
||||
}
|
||||
|
||||
/// full music record
|
||||
#[derive(Debug, Clone, PartialEq, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct DxMusicRecord {
|
||||
pub sheet_id: DxSheetId,
|
||||
pub achievement_rate: f64,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct DxSheetId {
|
||||
pub music_title: String,
|
||||
pub dx_version: bool,
|
||||
pub level: DxLevelName,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, strum::IntoStaticStr, strum::FromRepr)]
|
||||
#[strum(serialize_all = "lowercase")]
|
||||
#[repr(u32)]
|
||||
pub enum DxLevelName {
|
||||
Basic,
|
||||
Advanced,
|
||||
Expert,
|
||||
Master,
|
||||
ReMaster,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub enum DataVersion {
|
||||
Buddies,
|
||||
BuddiesPlus,
|
||||
Prism,
|
||||
PrismPlus,
|
||||
}
|
||||
|
||||
impl Serialize for DataVersion {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
serializer.serialize_str(match self {
|
||||
DataVersion::Buddies => "BUDDiES",
|
||||
DataVersion::BuddiesPlus => "BUDDiES PLUS",
|
||||
DataVersion::Prism => "PRiSM",
|
||||
DataVersion::PrismPlus => "PRiSM PLUS",
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for DxSheetId {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
serializer.serialize_str(&self.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl ToString for DxSheetId {
|
||||
fn to_string(&self) -> String {
|
||||
let mut output = self.music_title.clone();
|
||||
|
||||
if self.dx_version {
|
||||
output += "__dxrt__dx__dxrt__"
|
||||
} else {
|
||||
output += "__dxrt__std__dxrt__"
|
||||
}
|
||||
|
||||
output += self.level.into();
|
||||
|
||||
output
|
||||
}
|
||||
}
|
||||
|
||||
mod conversion;
|
||||
@@ -168,3 +168,5 @@ impl MusicRating {
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub mod dxrating;
|
||||
|
||||
@@ -14,4 +14,11 @@ mod get_user_data_api;
|
||||
pub use get_user_data_api::{GetUserDataApi, GetUserDataApiResp};
|
||||
|
||||
mod get_user_rating_api;
|
||||
pub use get_user_rating_api::dxrating::{
|
||||
DxCalculatedEntries, // entries
|
||||
DxLevelName, // level name
|
||||
DxMusicRecord,
|
||||
DxRatingNet,
|
||||
DxSheetId,
|
||||
};
|
||||
pub use get_user_rating_api::{GetUserRatingApi, GetUserRatingApiResp};
|
||||
|
||||
Reference in New Issue
Block a user