1use crate::arguments::PgArgumentBuffer;
2use crate::types::decode::Decode;
3use crate::types::encode::{Encode, IsNull};
4use crate::value::{PgValue, PgValueFormat};
5use byteorder::{BigEndian, ByteOrder};
6use rbdc::Error;
7use rbs::Value;
8use std::fmt::{Display, Formatter};
9
10#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, Eq, PartialEq)]
21#[serde(rename = "Money")]
22pub struct Money(pub i64);
23
24impl Display for Money {
25 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
26 write!(f, "{}", self.0)
27 }
28}
29
30impl From<Money> for Value {
31 fn from(arg: Money) -> Self {
32 Value::Ext("Money", Box::new(Value::I64(arg.0)))
33 }
34}
35
36impl Encode for Money {
37 fn encode(self, buf: &mut PgArgumentBuffer) -> Result<IsNull, Error> {
38 buf.extend(&self.0.to_be_bytes());
39 Ok(IsNull::No)
40 }
41}
42
43impl Decode for Money {
44 fn decode(value: PgValue) -> Result<Self, Error> {
45 Ok(Self({
46 match value.format() {
47 PgValueFormat::Binary => {
48 let cents = BigEndian::read_i64(value.as_bytes()?);
49 Ok(cents)
50 }
51 PgValueFormat::Text => Err(Error::from(
52 "Reading a `MONEY` value in text format is not supported.",
53 )),
54 }
55 }?))
56 }
57}