Skip to content

Commit

Permalink
feat: add serialize for TouchMode and TaskType enum
Browse files Browse the repository at this point in the history
  • Loading branch information
wangl-cc committed Nov 30, 2024
1 parent 96f3f62 commit 65bbb8c
Showing 1 changed file with 88 additions and 8 deletions.
96 changes: 88 additions & 8 deletions maa-types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ pub mod primitive {
}

/// Available static option key
#[repr(u8)]
#[derive(Clone, Copy)]
pub enum StaticOptionKey {
/// set to true to enable CPU OCR
Expand All @@ -31,6 +32,7 @@ pub enum StaticOptionKey {
}

/// Available instance option key
#[repr(u8)]
#[derive(Clone, Copy)]
pub enum InstanceOptionKey {
/// set touch mode of instance
Expand All @@ -44,6 +46,7 @@ pub enum InstanceOptionKey {
}

/// Available touch mode
#[repr(u8)]
#[derive(Default, Clone, Copy, PartialEq)]
pub enum TouchMode {
#[default]
Expand Down Expand Up @@ -128,13 +131,24 @@ impl<'de> serde::Deserialize<'de> for TouchMode {
{
struct TouchModeVisitor;

impl<'de> serde::de::Visitor<'de> for TouchModeVisitor {
impl serde::de::Visitor<'_> for TouchModeVisitor {
type Value = TouchMode;

fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("a valid touch mode")
}

fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
if v < TouchMode::COUNT as u64 {
Ok(unsafe { std::mem::transmute::<u8, TouchMode>(v as u8) })
} else {
Err(E::invalid_value(serde::de::Unexpected::Unsigned(v), &self))
}
}

fn visit_str<E>(self, value: &str) -> std::result::Result<TouchMode, E>
where
E: serde::de::Error,
Expand All @@ -148,6 +162,16 @@ impl<'de> serde::Deserialize<'de> for TouchMode {
}
}

#[cfg(feature = "serde")]
impl serde::Serialize for TouchMode {
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_u64(*self as u64)
}
}

impl std::fmt::Debug for TouchMode {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(self.to_str())
Expand All @@ -161,6 +185,7 @@ impl std::fmt::Display for TouchMode {
}

/// Available task type for MAA
#[repr(u8)]
#[derive(Clone, Copy, PartialEq, Eq)]
pub enum TaskType {
StartUp,
Expand Down Expand Up @@ -267,13 +292,24 @@ impl<'de> serde::Deserialize<'de> for TaskType {
{
struct TaskTypeVisitor;

impl<'de> serde::de::Visitor<'de> for TaskTypeVisitor {
impl serde::de::Visitor<'_> for TaskTypeVisitor {
type Value = TaskType;

fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("a valid task type")
}

fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
if v < TaskType::COUNT as u64 {
Ok(unsafe { std::mem::transmute::<u8, TaskType>(v as u8) })
} else {
Err(E::invalid_value(serde::de::Unexpected::Unsigned(v), &self))
}
}

fn visit_str<E>(self, value: &str) -> Result<TaskType, E>
where
E: serde::de::Error,
Expand All @@ -287,6 +323,16 @@ impl<'de> serde::Deserialize<'de> for TaskType {
}
}

#[cfg(feature = "serde")]
impl serde::Serialize for TaskType {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_u64(*self as u64)
}
}

impl std::fmt::Debug for TaskType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(self.to_str())
Expand Down Expand Up @@ -339,19 +385,41 @@ mod tests {

#[test]
fn deserialize() {
assert_de_tokens(&Adb, &[Token::Str("adb")]);
assert_de_tokens(&MiniTouch, &[Token::Str("minitouch")]);
assert_de_tokens(&MaaTouch, &[Token::Str("maatouch")]);
assert_de_tokens(&MacPlayTools, &[Token::Str("MacPlayTools")]);
let modes = [Adb, MiniTouch, MaaTouch, MacPlayTools];

// Test deserializing from string
assert_de_tokens(&modes, &[
Token::Seq { len: Some(4) },
Token::Str("adb"),
Token::Str("minitouch"),
Token::Str("maatouch"),
Token::Str("MacPlayTools"),
Token::SeqEnd,
]);

// Test deserializing from u64
assert_de_tokens(&modes, &[
Token::Seq { len: Some(4) },
Token::U64(0),
Token::U64(1),
Token::U64(2),
Token::U64(3),
Token::SeqEnd,
]);
}

#[test]
fn deserialize_unknown() {
fn deserialize_error() {
assert_de_tokens_error::<TouchMode>(
&[Token::Str("Unknown")],
"unknown variant `Unknown`, expected one of \
`adb`, `minitouch`, `maatouch`, `MacPlayTools`",
);

assert_de_tokens_error::<TouchMode>(
&[Token::U64(4)],
"invalid value: integer `4`, expected a valid touch mode",
);
}
}

Expand Down Expand Up @@ -421,16 +489,28 @@ mod tests {
Token::Str("CloseDown"),
Token::SeqEnd,
]);

assert_de_tokens(&types, &[
Token::Seq { len: Some(2) },
Token::U64(0),
Token::U64(1),
Token::SeqEnd,
]);
}

#[test]
fn deserialize_unknown_variance() {
fn deserialize_error() {
assert_de_tokens_error::<TaskType>(
&[Token::Str("Unknown")],
"unknown variant `Unknown`, expected one of `StartUp`, `CloseDown`, `Fight`, \
`Recruit`, `Infrast`, `Mall`, `Award`, `Roguelike`, `Copilot`, `SSSCopilot`, \
`Depot`, `OperBox`, `Reclamation`, `Custom`, `SingleStep`, `VideoRecognition`",
);

assert_de_tokens_error::<TaskType>(
&[Token::U64(16)],
"invalid value: integer `16`, expected a valid task type",
);
}
}

Expand Down

0 comments on commit 65bbb8c

Please sign in to comment.