1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
//! Serialization and deserialization using different formats and data types.
//!
//! # Examples
//!
//! Suppose you have a struct that you want to serialize to json and you want the BigFloat values contained in the struct to be exported as formatted strings.
//! The following is an example of how this can be achieved using `serde` field attributes and `num_bigfloat::serde::str` module:
//!
//! ``` rust
//! use num_bigfloat::BigFloat;
//! use serde::{Serialize, Deserialize};
//!
//! // A struct with a field of type BigFloat
//! #[derive(Serialize, Deserialize)]
//! struct SomeStruct {
//!
//! #[serde(with = "num_bigfloat::serde::str")]
//! pub f: BigFloat,
//! }
//!
//! // Value to be serialized
//! let f = BigFloat::parse("-1.234567890123456789012345678901234567890e-12").unwrap();
//! let val = SomeStruct {
//! f,
//! };
//!
//! // Serialization
//! let json = serde_json::to_string(&val).unwrap();
//!
//! // Result
//! assert_eq!("{\"f\":\"-1.234567890123456789012345678901234567890e-12\"}", json);
//! ```
pub mod str {
//! Serialization to string and deserialization from string.
use crate::util::WritableBuf;
use crate::BigFloat;
use core::str::from_utf8_unchecked;
use serde::Deserializer;
use serde::Serializer;
use serde::de::{self, Visitor};
struct StrVisitor;
impl<'de> Visitor<'de> for StrVisitor {
type Value = BigFloat;
fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result {
formatter.write_str("a string representation of BigFloat")
}
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: de::Error,
{
BigFloat::parse(value).ok_or_else(|| de::Error::custom("Failed to parse BigFloat"))
}
}
/// Serialize `f` to a string using given serializer.
pub fn serialize<S>(f: &BigFloat, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut buf = [0; 64];
let mut w = WritableBuf::new(&mut buf);
f.write_str(&mut w).unwrap();
let written_len = w.len();
let s = unsafe { from_utf8_unchecked(&buf[..written_len]) };
serializer.serialize_str(s)
}
/// Deserialize BigFloat from a string using given deserializer.
pub fn deserialize<'de, D>(deserializer: D) -> Result<BigFloat, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_str(StrVisitor)
}
}
#[cfg(test)]
mod tests {
use crate::BigFloat;
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)]
struct Stub {
#[serde(with = "crate::serde::str")]
pub f: BigFloat,
}
#[test]
fn test_serde_str() {
// serialize
let f = BigFloat::parse("-1.234567890123456789012345678901234567890e-12").unwrap();
let stub = Stub { f };
let json = serde_json::to_string(&stub).unwrap();
assert_eq!(
"{\"f\":\"-1.234567890123456789012345678901234567890e-12\"}",
json
);
// deserialize
let f = BigFloat::parse("+9.123456789012345678901234567890123456789e+12").unwrap();
let json = "{
\"f\": \"9.123456789012345678901234567890123456789e+12\"
}";
let stub: Stub = serde_json::from_str(json).unwrap();
assert!(stub.f.cmp(&f) == Some(0));
}
}