async_graphql/types/
id.rs1use std::{
2 num::ParseIntError,
3 ops::{Deref, DerefMut},
4};
5
6use async_graphql_value::ConstValue;
7use serde::{Deserialize, Serialize};
8
9use crate::{InputValueError, InputValueResult, Scalar, ScalarType, Value};
10
11#[derive(Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, Serialize, Deserialize, Default)]
16#[serde(transparent)]
17pub struct ID(pub String);
18
19impl AsRef<str> for ID {
20 fn as_ref(&self) -> &str {
21 self.0.as_str()
22 }
23}
24
25impl Deref for ID {
26 type Target = String;
27
28 fn deref(&self) -> &Self::Target {
29 &self.0
30 }
31}
32
33impl DerefMut for ID {
34 fn deref_mut(&mut self) -> &mut Self::Target {
35 &mut self.0
36 }
37}
38
39impl<T: std::fmt::Display> From<T> for ID {
40 fn from(value: T) -> Self {
41 ID(value.to_string())
42 }
43}
44
45impl From<ID> for String {
46 fn from(id: ID) -> Self {
47 id.0
48 }
49}
50
51impl From<ID> for ConstValue {
52 fn from(id: ID) -> Self {
53 ConstValue::String(id.0)
54 }
55}
56
57macro_rules! try_from_integers {
58 ($($ty:ty),*) => {
59 $(
60 impl TryFrom<ID> for $ty {
61 type Error = ParseIntError;
62
63 fn try_from(id: ID) -> Result<Self, Self::Error> {
64 id.0.parse()
65 }
66 }
67 )*
68 };
69}
70
71try_from_integers!(
72 i8, i16, i32, i64, i128, u8, u16, u32, u64, u128, isize, usize
73);
74
75#[cfg(feature = "uuid")]
76impl TryFrom<ID> for uuid::Uuid {
77 type Error = uuid::Error;
78
79 fn try_from(id: ID) -> Result<Self, Self::Error> {
80 uuid::Uuid::parse_str(&id.0)
81 }
82}
83
84impl PartialEq<&str> for ID {
85 fn eq(&self, other: &&str) -> bool {
86 self.0.as_str() == *other
87 }
88}
89
90#[Scalar(internal, name = "ID")]
91impl ScalarType for ID {
92 fn parse(value: Value) -> InputValueResult<Self> {
93 match value {
94 Value::Number(n) if n.is_i64() => Ok(ID(n.to_string())),
95 Value::String(s) => Ok(ID(s)),
96 _ => Err(InputValueError::expected_type(value)),
97 }
98 }
99
100 fn is_valid(value: &Value) -> bool {
101 match value {
102 Value::Number(n) if n.is_i64() => true,
103 Value::String(_) => true,
104 _ => false,
105 }
106 }
107
108 fn to_value(&self) -> Value {
109 Value::String(self.0.clone())
110 }
111}