mirror of https://github.com/dnaka91/obws
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
184 lines
5.0 KiB
Rust
184 lines
5.0 KiB
Rust
use std::fmt;
|
|
|
|
use serde::{
|
|
de::{self, Deserializer, Visitor},
|
|
ser::{SerializeMap, Serializer},
|
|
};
|
|
|
|
#[derive(Debug, thiserror::Error)]
|
|
enum Error<'a> {
|
|
#[error("track index `{0}` is out of range")]
|
|
OutOfRange(&'a str),
|
|
}
|
|
|
|
pub fn deserialize<'de, D>(deserializer: D) -> Result<[bool; 6], D::Error>
|
|
where
|
|
D: Deserializer<'de>,
|
|
{
|
|
deserializer.deserialize_map(AudioTracksVisitor)
|
|
}
|
|
|
|
struct AudioTracksVisitor;
|
|
|
|
impl<'de> Visitor<'de> for AudioTracksVisitor {
|
|
type Value = [bool; 6];
|
|
|
|
fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
formatter.write_str("audio tracks as key-value pairs")
|
|
}
|
|
|
|
fn visit_map<A>(self, mut access: A) -> Result<Self::Value, A::Error>
|
|
where
|
|
A: de::MapAccess<'de>,
|
|
{
|
|
let mut map = [false; 6];
|
|
|
|
while let Some((key, value)) = access.next_entry::<std::borrow::Cow<'_, str>, bool>()? {
|
|
let index = match key.as_ref() {
|
|
"1" | "2" | "3" | "4" | "5" | "6" => key.as_bytes()[0] - b'0' - 1,
|
|
_ => return Err(de::Error::custom(Error::OutOfRange(key.as_ref()))),
|
|
};
|
|
|
|
map[index as usize] = value;
|
|
}
|
|
|
|
Ok(map)
|
|
}
|
|
}
|
|
|
|
pub mod option {
|
|
use super::*;
|
|
|
|
pub fn serialize<S>(value: &[Option<bool>; 6], serializer: S) -> Result<S::Ok, S::Error>
|
|
where
|
|
S: Serializer,
|
|
{
|
|
let mut map = serializer.serialize_map(Some(value.iter().copied().flatten().count()))?;
|
|
for (k, v) in ["1", "2", "3", "4", "5", "6"]
|
|
.into_iter()
|
|
.zip(value)
|
|
.filter_map(|(k, v)| v.map(|v| (k, v)))
|
|
{
|
|
map.serialize_entry(k, &v)?;
|
|
}
|
|
map.end()
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use serde::{Deserialize, Serialize};
|
|
use serde_test::{assert_de_tokens, assert_de_tokens_error, assert_ser_tokens, Token};
|
|
|
|
#[derive(Debug, PartialEq, Serialize)]
|
|
struct SimpleTracksSer {
|
|
#[serde(with = "super::option")]
|
|
value: [Option<bool>; 6],
|
|
}
|
|
|
|
#[derive(Debug, PartialEq, Deserialize)]
|
|
struct SimpleTracksDe {
|
|
#[serde(with = "super")]
|
|
value: [bool; 6],
|
|
}
|
|
|
|
#[test]
|
|
fn roundtrip() {
|
|
assert_ser_tokens(
|
|
&SimpleTracksSer {
|
|
value: [Some(true), Some(true), None, None, Some(false), Some(true)],
|
|
},
|
|
&[
|
|
Token::Struct {
|
|
name: "SimpleTracksSer",
|
|
len: 1,
|
|
},
|
|
Token::Str("value"),
|
|
Token::Map { len: Some(4) },
|
|
Token::Str("1"),
|
|
Token::Bool(true),
|
|
Token::Str("2"),
|
|
Token::Bool(true),
|
|
Token::Str("5"),
|
|
Token::Bool(false),
|
|
Token::Str("6"),
|
|
Token::Bool(true),
|
|
Token::MapEnd,
|
|
Token::StructEnd,
|
|
],
|
|
);
|
|
|
|
assert_de_tokens(
|
|
&SimpleTracksDe {
|
|
value: [true, true, false, false, false, true],
|
|
},
|
|
&[
|
|
Token::Struct {
|
|
name: "SimpleTracksDe",
|
|
len: 1,
|
|
},
|
|
Token::Str("value"),
|
|
Token::Map { len: Some(6) },
|
|
Token::Str("1"),
|
|
Token::Bool(true),
|
|
Token::String("2"),
|
|
Token::Bool(true),
|
|
Token::BorrowedStr("3"),
|
|
Token::Bool(false),
|
|
Token::Str("4"),
|
|
Token::Bool(false),
|
|
Token::Str("5"),
|
|
Token::Bool(false),
|
|
Token::Str("6"),
|
|
Token::Bool(true),
|
|
Token::MapEnd,
|
|
Token::StructEnd,
|
|
],
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn deser() {
|
|
assert_de_tokens(
|
|
&SimpleTracksDe { value: [true; 6] },
|
|
&[
|
|
Token::Struct {
|
|
name: "SimpleTracksDe",
|
|
len: 1,
|
|
},
|
|
Token::Str("value"),
|
|
Token::Map { len: Some(6) },
|
|
Token::Str("1"),
|
|
Token::Bool(true),
|
|
Token::Str("2"),
|
|
Token::Bool(true),
|
|
Token::Str("3"),
|
|
Token::Bool(true),
|
|
Token::Str("4"),
|
|
Token::Bool(true),
|
|
Token::Str("5"),
|
|
Token::Bool(true),
|
|
Token::Str("6"),
|
|
Token::Bool(true),
|
|
Token::MapEnd,
|
|
Token::StructEnd,
|
|
],
|
|
);
|
|
|
|
assert_de_tokens_error::<SimpleTracksDe>(
|
|
&[
|
|
Token::Struct {
|
|
name: "SimpleTracksDe",
|
|
len: 1,
|
|
},
|
|
Token::Str("value"),
|
|
Token::Map { len: Some(1) },
|
|
Token::Str("10"),
|
|
Token::Bool(true),
|
|
Token::MapEnd,
|
|
],
|
|
"track index `10` is out of range",
|
|
);
|
|
}
|
|
}
|