I'm not able to do implement the bigdecimal by myself because I don't have experience enough with rust to do it.
I just know that is possible but don't know how, and I can't just use graphql_scalar! macro because it needs implementations on the struct.
You need to use a newtype, since you can't implement foreign traits on foreign structs.
struct MyBigDecimal(pub bigdecimal::BigDecimal);
juniper::graphql_scalar!( ..... );
But the 'MyBugDecimal' has to have all the implementations that the bigdecimal have to work properly with diesel (to diesel see as the same) right ?
@SharksT Does https://gitlab.com/williamyaoh/shrinkwraprs help with what you want?
this took me ages to piece together as I'm still trying to figure this stuff out, but I hope it helps. ;)
__dependencies__
juniper = "0.14.0"
serde = "1.0"
serde_derive = "1.0"
diesel = { version = "1.4.2", features = ["postgres", "numeric"] }
bigdecimal = { version = "0.0.14", features = ["serde"] }
use bigdecimal::BigDecimal;
use diesel::sql_types::Numeric;
use diesel::backend::Backend;
use diesel::deserialize::{FromSql};
use diesel::serialize::{ToSql, Output};
use serde::{Serialize, Serializer, Deserialize};
use serde::de::{
Deserializer,
self, Visitor,
};
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, FromSqlRow, AsExpression)]
#[sql_type = "Numeric"]
pub struct MyBigDecimal(pub BigDecimal);
impl Serialize for MyBigDecimal {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_newtype_struct("MyBigDecimal", &self.0)
}
}
struct MyBigDecimalVisitor;
impl<'de> Visitor<'de> for MyBigDecimalVisitor {
type Value = MyBigDecimal;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("a Decimal represented as a string.")
}
fn visit_str<E>(self, value: &str) -> Result<MyBigDecimal, E>
where
E: de::Error,
{
Ok(MyBigDecimal(BigDecimal::from_str(&value).unwrap()))
}
fn visit_f32<E>(self, value: f32) -> Result<MyBigDecimal, E>
where
E: de::Error,
{
Ok(MyBigDecimal(BigDecimal::from(value)))
}
fn visit_f64<E>(self, value: f64) -> Result<MyBigDecimal, E>
where
E: de::Error,
{
Ok(MyBigDecimal(BigDecimal::from(value)))
}
}
impl<'de> Deserialize<'de> for MyBigDecimal {
fn deserialize<D>(deserializer: D) -> Result<MyBigDecimal, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_any(MyBigDecimalVisitor)
}
}
impl<DB: Backend> ToSql<Numeric, DB> for MyBigDecimal
where
BigDecimal: ToSql<Numeric, DB>,
{
fn to_sql<W: std::io::Write>(&self, out: &mut Output<W, DB>) -> ::diesel::serialize::Result {
ToSql::<Numeric, DB>::to_sql(&self.0, out)
}
}
impl<DB: Backend> FromSql<Numeric, DB> for MyBigDecimal
where
BigDecimal: FromSql<Numeric, DB>,
{
fn from_sql(bytes: Option<&DB::RawValue>) -> diesel::deserialize::Result<Self> {
FromSql::<Numeric, DB>::from_sql(bytes).map(MyBigDecimal)
}
}
use juniper::{Value, ParseScalarResult, ParseScalarValue};
use std::str::FromStr;
graphql_scalar!(MyBigDecimal where Scalar = <S> {
description: "BigDecimal"
resolve(&self) -> Value {
Value::scalar(self.0.to_string())
}
from_input_value(v: &InputValue) -> Option<MyBigDecimal> {
v.as_scalar_value::<String>()
.and_then(|str_val|
match BigDecimal::from_str(&str_val) {
Ok(big_decimal) => Some(MyBigDecimal(big_decimal)),
Err(_) => None,
})
}
from_str<'a>(value: ScalarToken<'a>) -> ParseScalarResult<'a, S> {
<String as ParseScalarValue<S>>::from_str(value)
}
});
Hello, thank you very much for your taking your time to help out!
I'm getting an error in your code :
the trait boundbigdecimal::BigDecimal: errors::_IMPL_SERIALIZE_FOR_Error::_serde::Serializeis not satisfied
Whoops! I forgot to add the dependency version for BigDecimal. You need to use bigdecimal = "0.0.14"
I'm using that version
Try adding the serde feature to the bigdecimal dependency.
On Fri., 4 Oct. 2019, 10:35 pm Felipe Passos, notifications@github.com
wrote:
I'm using that version
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/graphql-rust/juniper/issues/429?email_source=notifications&email_token=ABCDTAZRENT2H6DIWGBPKTLQM4Z7HA5CNFSM4IZCSMYKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEALP7BY#issuecomment-538378119,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ABCDTA2BW2MNO53OBOHRFVTQM4Z7HANCNFSM4IZCSMYA
.
Now it's working, thank you so much !