Add StringNumber type.
This commit is contained in:
parent
3e19b23178
commit
089e830d26
|
@ -14,10 +14,11 @@ categories = ["network-programming", "asynchronous"]
|
|||
readme = "README.md"
|
||||
|
||||
[features]
|
||||
default = ["apollo_tracing", "uuid", "bson", "chrono", "chrono-tz", "log", "multipart", "tracing", "url", "unblock"]
|
||||
default = ["apollo_tracing", "uuid", "bson", "chrono", "chrono-tz", "log", "multipart", "tracing", "url", "unblock", "string_number"]
|
||||
apollo_tracing = ["chrono"]
|
||||
multipart = ["multer", "bytes", "tempfile"]
|
||||
unblock = ["blocking"]
|
||||
string_number = ["num-traits"]
|
||||
# Used for doc(cfg())
|
||||
nightly = []
|
||||
|
||||
|
@ -47,6 +48,7 @@ chrono-tz = { version = "0.5.1", optional = true }
|
|||
log = { version = "0.4.11", optional = true }
|
||||
tracing = { version = "0.1.19", optional = true }
|
||||
url = { version = "2.1.1", optional = true }
|
||||
num-traits = { version = "0.2.12", optional = true }
|
||||
|
||||
bytes = { version = "0.5.4", optional = true }
|
||||
multer = { version = "1.2.2", optional = true }
|
||||
|
|
|
@ -10,6 +10,8 @@ mod json;
|
|||
mod maybe_undefined;
|
||||
mod merged_object;
|
||||
mod query_root;
|
||||
#[cfg(feature = "string_number")]
|
||||
mod string_number;
|
||||
mod upload;
|
||||
|
||||
mod external;
|
||||
|
@ -21,6 +23,8 @@ pub use id::ID;
|
|||
pub use json::{Json, OutputJson};
|
||||
pub use maybe_undefined::MaybeUndefined;
|
||||
pub use merged_object::{MergedObject, MergedObjectSubscriptionTail, MergedObjectTail};
|
||||
#[cfg(feature = "string_number")]
|
||||
pub use string_number::StringNumber;
|
||||
pub use upload::Upload;
|
||||
|
||||
pub(crate) use query_root::QueryRoot;
|
||||
|
|
78
src/types/string_number.rs
Normal file
78
src/types/string_number.rs
Normal file
|
@ -0,0 +1,78 @@
|
|||
use crate::{InputValueError, InputValueResult, Scalar, ScalarType, Value};
|
||||
use num_traits::Num;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt::Display;
|
||||
|
||||
/// A numeric value represented by a string.
|
||||
#[derive(Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, Serialize, Deserialize)]
|
||||
#[serde(transparent)]
|
||||
#[cfg_attr(feature = "nightly", doc(cfg(feature = "string_number")))]
|
||||
pub struct StringNumber<T: Num + Display>(pub T);
|
||||
|
||||
#[Scalar(internal)]
|
||||
impl<T: Num + Display + Send + Sync> ScalarType for StringNumber<T>
|
||||
where
|
||||
<T as Num>::FromStrRadixErr: Display,
|
||||
{
|
||||
fn parse(value: Value) -> InputValueResult<Self> {
|
||||
match value {
|
||||
Value::String(s) => {
|
||||
let n = T::from_str_radix(&s, 10)
|
||||
.map_err(|err| InputValueError::Custom(err.to_string()))?;
|
||||
Ok(StringNumber(n))
|
||||
}
|
||||
_ => Err(InputValueError::ExpectedType(value)),
|
||||
}
|
||||
}
|
||||
|
||||
fn is_valid(value: &Value) -> bool {
|
||||
match value {
|
||||
Value::String(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn to_value(&self) -> Value {
|
||||
Value::String(self.0.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::*;
|
||||
|
||||
#[async_std::test]
|
||||
async fn test_string_number() {
|
||||
struct Query;
|
||||
|
||||
#[Object(internal)]
|
||||
impl Query {
|
||||
async fn value(&self, n: StringNumber<i32>) -> StringNumber<i32> {
|
||||
n
|
||||
}
|
||||
}
|
||||
|
||||
let schema = Schema::new(Query, EmptyMutation, EmptySubscription);
|
||||
assert_eq!(
|
||||
schema
|
||||
.execute(
|
||||
r#"{
|
||||
value1: value(n: "100")
|
||||
value2: value(n: "-100")
|
||||
value3: value(n: "0")
|
||||
value4: value(n: "1")
|
||||
}"#
|
||||
)
|
||||
.await
|
||||
.into_result()
|
||||
.unwrap()
|
||||
.data,
|
||||
serde_json::json!({
|
||||
"value1": "100",
|
||||
"value2": "-100",
|
||||
"value3": "0",
|
||||
"value4": "1",
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user