Skip to content

Commit f818d7e

Browse files
committed
Deserializing BDAddr from non-borrowed string without clone #70ee65cc
1 parent 5f64e11 commit f818d7e

File tree

2 files changed

+54
-12
lines changed

2 files changed

+54
-12
lines changed

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -81,3 +81,4 @@ rand = "0.8.5"
8181
pretty_env_logger = "0.5.0"
8282
tokio = { version = "1.40.0", features = ["macros", "rt", "rt-multi-thread"] }
8383
serde_json = "1.0.128"
84+
toml = "0.8.19"

src/api/bdaddr.rs

+53-12
Original file line numberDiff line numberDiff line change
@@ -266,12 +266,11 @@ pub mod serde {
266266
where
267267
D: Deserializer<'de>,
268268
{
269-
let buf = d.deserialize_str(ColonDelimVisitor)?;
270-
BDAddr::from_str_delim(&buf).map_err(D::Error::custom)
269+
d.deserialize_str(ColonDelimVisitor)
271270
}
272271

273272
impl<'de> Visitor<'de> for ColonDelimVisitor {
274-
type Value = Cow<'de, str>;
273+
type Value = BDAddr;
275274

276275
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
277276
write!(
@@ -284,21 +283,21 @@ pub mod serde {
284283
where
285284
E: DeError,
286285
{
287-
Ok(v.to_string().into())
286+
BDAddr::from_str_delim(v).map_err(E::custom)
288287
}
289288

290289
fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
291290
where
292291
E: DeError,
293292
{
294-
Ok(v.into())
293+
BDAddr::from_str_delim(v).map_err(E::custom)
295294
}
296295

297296
fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
298297
where
299298
E: DeError,
300299
{
301-
Ok(v.into())
300+
BDAddr::from_str_delim(&v).map_err(E::custom)
302301
}
303302
}
304303
}
@@ -343,12 +342,11 @@ pub mod serde {
343342
where
344343
D: Deserializer<'de>,
345344
{
346-
let buf = d.deserialize_str(NoDelimVisitor)?;
347-
BDAddr::from_str_no_delim(&buf).map_err(D::Error::custom)
345+
d.deserialize_str(NoDelimVisitor)
348346
}
349347

350348
impl<'de> Visitor<'de> for NoDelimVisitor {
351-
type Value = Cow<'de, str>;
349+
type Value = BDAddr;
352350

353351
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
354352
write!(
@@ -361,21 +359,21 @@ pub mod serde {
361359
where
362360
E: DeError,
363361
{
364-
Ok(v.to_string().into())
362+
BDAddr::from_str_no_delim(v).map_err(E::custom)
365363
}
366364

367365
fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
368366
where
369367
E: DeError,
370368
{
371-
Ok(v.into())
369+
BDAddr::from_str_no_delim(v).map_err(E::custom)
372370
}
373371

374372
fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
375373
where
376374
E: DeError,
377375
{
378-
Ok(v.into())
376+
BDAddr::from_str_no_delim(&v).map_err(E::custom)
379377
}
380378
}
381379
}
@@ -481,4 +479,47 @@ mod tests {
481479
let addr_back: BDAddr = addr_as_hex.try_into().unwrap();
482480
assert_eq!(ADDR, addr_back);
483481
}
482+
483+
#[cfg(feature = "serde")]
484+
#[test]
485+
fn deserialize_toml_delim_bdaddr_with_struct() {
486+
use serde_cr::Deserialize;
487+
488+
#[derive(Deserialize, PartialEq, Copy, Clone, Debug)]
489+
#[serde(crate = "serde_cr")]
490+
struct Data {
491+
addr: BDAddr,
492+
}
493+
494+
let data = Data {
495+
addr: BDAddr::from([0xff, 0x00, 0xff, 0x00, 0xff, 0x00]),
496+
};
497+
498+
assert_eq!(toml::from_str(r#"addr = "ff:00:ff:00:ff:00""#), Ok(data));
499+
assert!(
500+
matches!(toml::from_str::<Data>(r"addr = 0"), Err(e) if e.message().contains("A colon seperated Bluetooth address, like `00:11:22:33:44:55`"))
501+
);
502+
}
503+
504+
#[cfg(feature = "serde")]
505+
#[test]
506+
fn deserialize_toml_nodelim_bdaddr_with_struct() {
507+
use serde_cr::Deserialize;
508+
509+
#[derive(Deserialize, PartialEq, Copy, Clone, Debug)]
510+
#[serde(crate = "serde_cr")]
511+
struct Data {
512+
#[serde(with = "crate::serde::bdaddr::no_delim")]
513+
addr: BDAddr,
514+
}
515+
516+
let data = Data {
517+
addr: BDAddr::from([0xff, 0x00, 0xff, 0x00, 0xff, 0x00]),
518+
};
519+
520+
assert_eq!(toml::from_str(r#"addr = "ff00ff00ff00""#), Ok(data));
521+
assert!(
522+
matches!(toml::from_str::<Data>(r"addr = 0"), Err(e) if e.message().contains("A Bluetooth address without any delimiters, like `001122334455`")),
523+
);
524+
}
484525
}

0 commit comments

Comments
 (0)