1use serde::de::Error;
2use serde::de::Unexpected;
3use serde::Deserialize;
4use serde::Deserializer;
5
6const IMDB_ID_EXPECT: &str = "a string starting with 'tt', followed by a positive integer";
7
8#[inline]
9pub fn parse_imdb_id<'de, D: Deserializer<'de>>(deserializer: D) -> Result<u32, D::Error> {
10 let s: &str = Deserialize::deserialize(deserializer)?;
11 if(s.len() < 2 || &s[0..=1] != "tt") {
12 return Err(Error::invalid_value(Unexpected::Str(s), &IMDB_ID_EXPECT));
13 }
14 match s[2..].parse() {
15 Ok(v) => Ok(v),
16 Err(_) => Err(Error::invalid_value(Unexpected::Str(s), &IMDB_ID_EXPECT))
17 }
18}
19
20#[inline]
21pub fn parse_janky_tsv_option<'de, D: Deserializer<'de>>(deserializer: D) -> Result<Option<u16>, D::Error> {
22 use core::num::IntErrorKind;
23
24 let s: &str = Deserialize::deserialize(deserializer)?;
25 if(s == "\\N") {
26 return Ok(None);
27 }
28 match s.parse() {
29 Ok(v) => Ok(Some(v)),
30 Err(e) if *e.kind() == IntErrorKind::PosOverflow => Ok(None),
31 Err(_) => Err(Error::invalid_type(Unexpected::Str(s), &"an unsigned 16-bit integer, or '\\N'"))
32 }
33}
34
35#[inline]
36pub fn parse_janky_tsv_option_u32<'de, D: Deserializer<'de>>(deserializer: D) -> Result<Option<u32>, D::Error> {
37 let s: &str = Deserialize::deserialize(deserializer)?;
38 if(s == "\\N") {
39 return Ok(None);
40 }
41 match s.parse() {
42 Ok(v) => Ok(Some(v)),
43 Err(_) => Err(Error::invalid_type(Unexpected::Str(s), &"an unsigned 32-bit integer, or '\\N'"))
44 }
45}
46