conjure_object/any/
mod.rs

1// Copyright 2020 Palantir Technologies, Inc.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14//! The Conjure `any` type.
15
16use crate::any::ser::AnySerializer;
17use ordered_float::OrderedFloat;
18use serde::de::{DeserializeOwned, Unexpected};
19use serde::Serialize;
20use std::collections::BTreeMap;
21use std::error;
22use std::f64;
23use std::fmt;
24
25mod de;
26mod ser;
27
28/// An error serializing to or from an `Any` value.
29#[derive(Debug)]
30pub struct Error(String);
31
32impl error::Error for Error {}
33
34impl fmt::Display for Error {
35    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
36        fmt.write_str(&self.0)
37    }
38}
39
40impl serde::de::Error for Error {
41    fn custom<T>(msg: T) -> Self
42    where
43        T: fmt::Display,
44    {
45        Error(msg.to_string())
46    }
47}
48
49impl serde::ser::Error for Error {
50    fn custom<T>(msg: T) -> Self
51    where
52        T: fmt::Display,
53    {
54        Error(msg.to_string())
55    }
56}
57
58#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
59enum Inner {
60    Null,
61    Bool(bool),
62    I8(i8),
63    I16(i16),
64    I32(i32),
65    I64(i64),
66    I128(i128),
67    U8(u8),
68    U16(u16),
69    U32(u32),
70    U64(u64),
71    U128(u128),
72    F32(OrderedFloat<f32>),
73    F64(OrderedFloat<f64>),
74    Char(char),
75    String(String),
76    Bytes(Vec<u8>),
77    Seq(Vec<Any>),
78    Map(BTreeMap<Any, Any>),
79}
80
81/// A representation of an arbitrary serializable value, corresponding to the Conjure `any` type.
82///
83/// The type is designed to be a lossless representation of a Conjure JSON value and follows Conjure's specifications
84/// regarding various edge cases such as base64 encoded binary values and non-finite floats. Its internal structure is
85/// opaque. Values can be converted to and from it with the `Any::new` and `Any::deserialize_into` methods, and it can
86/// be deserialized to and from JSON via its `Serialize` and `Deserialize` implementations.
87#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
88pub struct Any(Inner);
89
90impl Any {
91    /// Converts a value into an `Any`.
92    ///
93    /// # Errors
94    ///
95    /// Returns an error if the value's serialize implementation returns an error or it does not serialize to a
96    /// JSON-compatible representation.
97    pub fn new<T>(value: T) -> Result<Any, Error>
98    where
99        T: Serialize,
100    {
101        value.serialize(AnySerializer)
102    }
103
104    /// Converts the `Any` into a typed value.
105    ///
106    /// This is simply a convenience function using `Any`'s `Deserializer` implementation.
107    ///
108    /// # Errors
109    ///
110    /// Returns an error if the type cannot be deserialized from this `Any`.
111    pub fn deserialize_into<T>(self) -> Result<T, Error>
112    where
113        T: DeserializeOwned,
114    {
115        T::deserialize(self)
116    }
117
118    fn unexpected(&self) -> Unexpected<'_> {
119        match &self.0 {
120            Inner::Null => Unexpected::Unit,
121            Inner::Bool(v) => Unexpected::Bool(*v),
122            Inner::I8(v) => Unexpected::Signed(i64::from(*v)),
123            Inner::I16(v) => Unexpected::Signed(i64::from(*v)),
124            Inner::I32(v) => Unexpected::Signed(i64::from(*v)),
125            Inner::I64(v) => Unexpected::Signed(*v),
126            Inner::I128(v) => Unexpected::Signed(*v as i64),
127            Inner::U8(v) => Unexpected::Unsigned(u64::from(*v)),
128            Inner::U16(v) => Unexpected::Unsigned(u64::from(*v)),
129            Inner::U32(v) => Unexpected::Unsigned(u64::from(*v)),
130            Inner::U64(v) => Unexpected::Unsigned(*v),
131            Inner::U128(v) => Unexpected::Unsigned(*v as u64),
132            Inner::F32(v) => Unexpected::Float(v.0 as f64),
133            Inner::F64(v) => Unexpected::Float(v.0),
134            Inner::Char(v) => Unexpected::Char(*v),
135            Inner::String(v) => Unexpected::Str(v),
136            Inner::Bytes(v) => Unexpected::Bytes(v),
137            Inner::Seq(_) => Unexpected::Seq,
138            Inner::Map(_) => Unexpected::Map,
139        }
140    }
141}