ckb_sentry_types/
project_id.rs1use std::convert::TryFrom;
2use std::fmt;
3use std::str::FromStr;
4
5use serde::{Deserialize, Serialize};
6use thiserror::Error;
7
8#[derive(Debug, Error, PartialEq, Eq, PartialOrd, Ord)]
10pub enum ParseProjectIdError {
11 #[error("invalid value for project id")]
13 InvalidValue,
14 #[error("empty or missing project id")]
16 EmptyValue,
17}
18
19#[derive(Copy, Clone, Debug, PartialEq, Eq, Ord, PartialOrd, Hash, Deserialize, Serialize)]
21pub struct ProjectId(u64);
22
23impl ProjectId {
24 #[inline]
26 pub fn new(id: u64) -> Self {
27 Self(id)
28 }
29
30 #[inline]
32 pub fn value(self) -> u64 {
33 self.0
34 }
35}
36
37impl fmt::Display for ProjectId {
38 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
39 write!(f, "{}", self.value())
40 }
41}
42
43macro_rules! impl_from {
44 ($ty:ty) => {
45 impl From<$ty> for ProjectId {
46 #[inline]
47 fn from(val: $ty) -> Self {
48 Self::new(val as u64)
49 }
50 }
51 };
52}
53
54impl_from!(u8);
55impl_from!(u16);
56impl_from!(u32);
57impl_from!(u64);
58
59macro_rules! impl_try_from {
60 ($ty:ty) => {
61 impl TryFrom<$ty> for ProjectId {
62 type Error = ParseProjectIdError;
63
64 #[inline]
65 fn try_from(val: $ty) -> Result<Self, Self::Error> {
66 match u64::try_from(val) {
67 Ok(id) => Ok(Self::new(id)),
68 Err(_) => Err(ParseProjectIdError::InvalidValue),
69 }
70 }
71 }
72 };
73}
74
75impl_try_from!(usize);
76impl_try_from!(i8);
77impl_try_from!(i16);
78impl_try_from!(i32);
79impl_try_from!(i64);
80
81impl FromStr for ProjectId {
82 type Err = ParseProjectIdError;
83
84 fn from_str(s: &str) -> Result<ProjectId, ParseProjectIdError> {
85 if s.is_empty() {
86 return Err(ParseProjectIdError::EmptyValue);
87 }
88
89 match s.parse::<u64>() {
90 Ok(val) => Ok(ProjectId::new(val)),
91 Err(_) => Err(ParseProjectIdError::InvalidValue),
92 }
93 }
94}
95
96#[cfg(test)]
97mod test {
98 use super::*;
99
100 #[test]
101 fn test_basic_api() {
102 let id: ProjectId = "42".parse().unwrap();
103 assert_eq!(id, ProjectId::new(42));
104 assert_eq!(
105 "42xxx".parse::<ProjectId>(),
106 Err(ParseProjectIdError::InvalidValue)
107 );
108 assert_eq!(
109 "".parse::<ProjectId>(),
110 Err(ParseProjectIdError::EmptyValue)
111 );
112 assert_eq!(ProjectId::new(42).to_string(), "42");
113
114 assert_eq!(serde_json::to_string(&ProjectId::new(42)).unwrap(), "42");
115 assert_eq!(
116 serde_json::from_str::<ProjectId>("42").unwrap(),
117 ProjectId::new(42)
118 );
119 }
120}