2020-04-15 03:15:30 +00:00
# Custom scalars
2020-05-09 22:37:31 +00:00
2020-09-01 05:47:22 +00:00
In `Async-graphql` most common scalar types are built in, but you can also create your own scalar types.
2020-05-09 22:37:31 +00:00
Using `async-graphql::Scalar` , you can add support for a scalar when you implement it. You only need to implement parsing and output functions.
2020-09-01 05:47:22 +00:00
The following example defines a 64-bit integer scalar where its input and output are strings. (Note: `Async-graphql` already supports 64-bit integers and uses strings as input and output.)
2020-05-09 22:37:31 +00:00
```rust
use async_graphql::*;
struct StringNumber(i64);
2020-09-18 00:52:13 +00:00
#[Scalar]
2020-05-09 22:37:31 +00:00
impl ScalarType for StringNumber {
2020-05-11 13:47:24 +00:00
fn parse(value: Value) -> InputValueResult< Self > {
2020-07-28 14:13:07 +00:00
if let Value::String(value) = & value {
2020-05-09 22:37:31 +00:00
// Parse the integer value
2020-07-28 14:13:07 +00:00
Ok(value.parse().map(StringNumber)?)
2020-05-09 22:37:31 +00:00
} else {
2020-05-10 10:27:46 +00:00
// If the type does not match
2020-10-04 09:21:53 +00:00
Err(InputValueError::expected_type(value))
2020-05-09 22:37:31 +00:00
}
}
2020-05-26 15:27:50 +00:00
fn to_value(& self) -> Value {
Value::String(self.0.to_string())
2020-05-09 22:37:31 +00:00
}
}
```
2020-10-12 23:35:30 +00:00
## Use `scalar!` macro to define scalar
If your type implemented `serde::Serialize` and `serde::Deserialize` , then you can use this macro to define a scalar more simply.
```rust
#[derive(Serialize, Deserialize)]
struct MyValue {
a: i32,
b: HashMap< String , i32 > ,
}
scalar!(MyValue);
// Rename to `MV` .
// scalar!(MyValue, "MV");
// Rename to `MV` and add description.
// scalar!(MyValue, "MV", "This is my value");
```