From 35b19a9029f0419413780741438de6352e161b38 Mon Sep 17 00:00:00 2001 From: Jesse de Wit Date: Sat, 28 Sep 2024 14:24:41 +0200 Subject: [PATCH] JSON serialize Vec fields as hex serde_json has no simple way to serialize specific field types as hex, until specialization is merged. This commit contains a hack to serialize all Vec fields as hex anyway. It is impossible to check the type of a generic type parameter at runtime. So all values are first serialized, then attempted to deserialize into a Vec. If that works, the found vector will be serialized as a hex string, rather than an array of numbers. This is not a performant machanism, but it gets the job done. As long as it is only used for dev commands and diagnostic data it should be fine. At least all those number arrays in the diagnostic data are now gone, without having to duplicate every struct definition just for serialization. Note that the 'Value' serialization is a copy of the real one. --- libs/Cargo.lock | 5 +- libs/sdk-core/Cargo.toml | 1 + libs/sdk-core/src/breez_services.rs | 22 +- libs/sdk-core/src/greenlight/node_api.rs | 14 +- libs/sdk-core/src/lib.rs | 1 + libs/sdk-core/src/serializer.rs | 896 +++++++++++++++++++++++ tools/sdk-cli/Cargo.lock | 5 +- 7 files changed, 923 insertions(+), 21 deletions(-) create mode 100644 libs/sdk-core/src/serializer.rs diff --git a/libs/Cargo.lock b/libs/Cargo.lock index 02a7e5269..b3344141b 100644 --- a/libs/Cargo.lock +++ b/libs/Cargo.lock @@ -647,6 +647,7 @@ dependencies = [ "ripemd", "rusqlite", "rusqlite_migration", + "ryu", "sdk-common", "serde", "serde_json", @@ -3077,9 +3078,9 @@ checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" [[package]] name = "ryu" -version = "1.0.15" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "schannel" diff --git a/libs/sdk-core/Cargo.toml b/libs/sdk-core/Cargo.toml index 1a1fb5495..118261dd3 100644 --- a/libs/sdk-core/Cargo.toml +++ b/libs/sdk-core/Cargo.toml @@ -51,6 +51,7 @@ miniz_oxide = "0.7.1" tokio-stream = "0.1.14" serde_with = "3.3.0" regex = { workspace = true } +ryu = "1.0.18" [dev-dependencies] mockito = { workspace = true } diff --git a/libs/sdk-core/src/breez_services.rs b/libs/sdk-core/src/breez_services.rs index f46763ae9..e61aae281 100644 --- a/libs/sdk-core/src/breez_services.rs +++ b/libs/sdk-core/src/breez_services.rs @@ -1149,7 +1149,7 @@ impl BreezServices { Ok(dev_cmd) => match dev_cmd { DevCommand::GenerateDiagnosticData => self.generate_diagnostic_data().await, }, - Err(_) => Ok(serde_json::to_string_pretty( + Err(_) => Ok(crate::serializer::to_string_pretty( &self.node_api.execute_command(command).await?, )?), } @@ -1176,7 +1176,7 @@ impl BreezServices { "node": node_data, "sdk": sdk_data }); - Ok(serde_json::to_string_pretty(&result)?) + Ok(crate::serializer::to_string_pretty(&result)?) } /// This method sync the local state with the remote node state. @@ -2171,18 +2171,20 @@ impl BreezServices { } async fn generate_sdk_diagnostic_data(&self) -> SdkResult { - let state = serde_json::to_value(&self.persister.get_node_state()?)?; - let payments = serde_json::to_value( + let state = crate::serializer::value::to_value(&self.persister.get_node_state()?)?; + let payments = crate::serializer::value::to_value( &self .persister .list_payments(ListPaymentsRequest::default())?, )?; - let channels = serde_json::to_value(&self.persister.list_channels()?)?; - let settings = serde_json::to_value(&self.persister.list_settings()?)?; - let reverse_swaps = - serde_json::to_value(self.persister.list_reverse_swaps().map(sanitize_vec)?)?; - let swaps = serde_json::to_value(self.persister.list_swaps().map(sanitize_vec)?)?; - let lsp_id = serde_json::to_value(&self.persister.get_lsp_id()?)?; + let channels = crate::serializer::value::to_value(&self.persister.list_channels()?)?; + let settings = crate::serializer::value::to_value(&self.persister.list_settings()?)?; + let reverse_swaps = crate::serializer::value::to_value( + self.persister.list_reverse_swaps().map(sanitize_vec)?, + )?; + let swaps = + crate::serializer::value::to_value(self.persister.list_swaps().map(sanitize_vec)?)?; + let lsp_id = crate::serializer::value::to_value(&self.persister.get_lsp_id()?)?; let res = json!({ "node_state": state, diff --git a/libs/sdk-core/src/greenlight/node_api.rs b/libs/sdk-core/src/greenlight/node_api.rs index b23fc92c8..67ad629b9 100644 --- a/libs/sdk-core/src/greenlight/node_api.rs +++ b/libs/sdk-core/src/greenlight/node_api.rs @@ -1765,7 +1765,7 @@ impl NodeAPI for Greenlight { .await? .into_inner(); - Ok(serde_json::to_value(&resp)?) + Ok(crate::serializer::value::to_value(&resp)?) } NodeCommand::ListPeerChannels => { let resp = self @@ -1774,7 +1774,7 @@ impl NodeAPI for Greenlight { .list_peer_channels(cln::ListpeerchannelsRequest::default()) .await? .into_inner(); - Ok(serde_json::to_value(&resp)?) + Ok(crate::serializer::value::to_value(&resp)?) } NodeCommand::ListFunds => { let resp = self @@ -1783,7 +1783,7 @@ impl NodeAPI for Greenlight { .list_funds(cln::ListfundsRequest::default()) .await? .into_inner(); - Ok(serde_json::to_value(&resp)?) + Ok(crate::serializer::value::to_value(&resp)?) } NodeCommand::ListPayments => { let resp = self @@ -1792,7 +1792,7 @@ impl NodeAPI for Greenlight { .list_pays(cln::ListpaysRequest::default()) .await? .into_inner(); - Ok(serde_json::to_value(&resp)?) + Ok(crate::serializer::value::to_value(&resp)?) } NodeCommand::ListInvoices => { let resp = self @@ -1801,7 +1801,7 @@ impl NodeAPI for Greenlight { .list_invoices(cln::ListinvoicesRequest::default()) .await? .into_inner(); - Ok(serde_json::to_value(&resp)?) + Ok(crate::serializer::value::to_value(&resp)?) } NodeCommand::CloseAllChannels => { let peers_res = self @@ -1823,7 +1823,7 @@ impl NodeAPI for Greenlight { .getinfo(cln::GetinfoRequest::default()) .await? .into_inner(); - Ok(serde_json::to_value(&resp)?) + Ok(crate::serializer::value::to_value(&resp)?) } NodeCommand::Stop => { let resp = self @@ -1832,7 +1832,7 @@ impl NodeAPI for Greenlight { .stop(cln::StopRequest::default()) .await? .into_inner(); - Ok(serde_json::to_value(&resp)?) + Ok(crate::serializer::value::to_value(&resp)?) } } } diff --git a/libs/sdk-core/src/lib.rs b/libs/sdk-core/src/lib.rs index 4859002c0..ef4583bb0 100644 --- a/libs/sdk-core/src/lib.rs +++ b/libs/sdk-core/src/lib.rs @@ -178,6 +178,7 @@ mod lsps0; mod lsps2; mod models; mod persist; +mod serializer; mod support; mod swap_in; mod swap_out; diff --git a/libs/sdk-core/src/serializer.rs b/libs/sdk-core/src/serializer.rs new file mode 100644 index 000000000..59a6b74e5 --- /dev/null +++ b/libs/sdk-core/src/serializer.rs @@ -0,0 +1,896 @@ +use serde::{ser::SerializeStruct, Serialize}; + +pub fn to_string_pretty(value: &T) -> serde_json::Result +where + T: ?Sized + Serialize, +{ + let vec = to_vec_pretty(value)?; + let string = unsafe { + // We do not emit invalid UTF-8. + String::from_utf8_unchecked(vec) + }; + Ok(string) +} + +pub fn to_vec_pretty(value: &T) -> serde_json::Result> +where + T: ?Sized + Serialize, +{ + let mut writer = Vec::with_capacity(128); + to_writer_pretty(&mut writer, value)?; + Ok(writer) +} + +pub fn to_writer_pretty(writer: W, value: &T) -> serde_json::Result<()> +where + W: std::io::Write, + T: ?Sized + Serialize, +{ + let mut ser = serde_json::Serializer::pretty(writer); + let ser = HexSerializer::new(&mut ser); + value.serialize(ser) +} + +pub struct HexSerializer +where + S: serde::ser::Serializer, +{ + inner: S, +} + +impl HexSerializer +where + S: serde::ser::Serializer, +{ + pub fn new(inner: S) -> Self { + Self { inner } + } +} + +impl<'a, S: 'a> serde::ser::Serializer for HexSerializer +where + S: serde::ser::Serializer, +{ + type Ok = S::Ok; + type Error = S::Error; + + type SerializeSeq = S::SerializeSeq; + type SerializeTuple = S::SerializeTuple; + type SerializeTupleStruct = S::SerializeTupleStruct; + type SerializeTupleVariant = S::SerializeTupleVariant; + type SerializeMap = S::SerializeMap; + type SerializeStruct = HexSerializeStruct; + type SerializeStructVariant = S::SerializeStructVariant; + + fn serialize_bool(self, v: bool) -> Result { + self.inner.serialize_bool(v) + } + + fn serialize_i8(self, v: i8) -> Result { + self.inner.serialize_i8(v) + } + + fn serialize_i16(self, v: i16) -> Result { + self.inner.serialize_i16(v) + } + + fn serialize_i32(self, v: i32) -> Result { + self.inner.serialize_i32(v) + } + + fn serialize_i64(self, v: i64) -> Result { + self.inner.serialize_i64(v) + } + + fn serialize_u8(self, v: u8) -> Result { + self.inner.serialize_u8(v) + } + + fn serialize_u16(self, v: u16) -> Result { + self.inner.serialize_u16(v) + } + + fn serialize_u32(self, v: u32) -> Result { + self.inner.serialize_u32(v) + } + + fn serialize_u64(self, v: u64) -> Result { + self.inner.serialize_u64(v) + } + + fn serialize_f32(self, v: f32) -> Result { + self.inner.serialize_f32(v) + } + + fn serialize_f64(self, v: f64) -> Result { + self.inner.serialize_f64(v) + } + + fn serialize_char(self, v: char) -> Result { + self.inner.serialize_char(v) + } + + fn serialize_str(self, v: &str) -> Result { + self.inner.serialize_str(v) + } + + fn serialize_bytes(self, v: &[u8]) -> Result { + self.inner.serialize_bytes(v) + } + + fn serialize_none(self) -> Result { + self.inner.serialize_none() + } + + fn serialize_some(self, value: &T) -> Result + where + T: ?Sized + Serialize, + { + self.inner.serialize_some(value) + } + + fn serialize_unit(self) -> Result { + self.inner.serialize_unit() + } + + fn serialize_unit_struct(self, name: &'static str) -> Result { + self.inner.serialize_unit_struct(name) + } + + fn serialize_unit_variant( + self, + name: &'static str, + variant_index: u32, + variant: &'static str, + ) -> Result { + self.inner + .serialize_unit_variant(name, variant_index, variant) + } + + fn serialize_newtype_struct( + self, + name: &'static str, + value: &T, + ) -> Result + where + T: ?Sized + Serialize, + { + self.inner.serialize_newtype_struct(name, value) + } + + fn serialize_newtype_variant( + self, + name: &'static str, + variant_index: u32, + variant: &'static str, + value: &T, + ) -> Result + where + T: ?Sized + Serialize, + { + self.inner + .serialize_newtype_variant(name, variant_index, variant, value) + } + + fn serialize_seq(self, len: Option) -> Result { + self.inner.serialize_seq(len) + } + + fn serialize_tuple(self, len: usize) -> Result { + self.inner.serialize_tuple(len) + } + + fn serialize_tuple_struct( + self, + name: &'static str, + len: usize, + ) -> Result { + self.inner.serialize_tuple_struct(name, len) + } + + fn serialize_tuple_variant( + self, + name: &'static str, + variant_index: u32, + variant: &'static str, + len: usize, + ) -> Result { + self.inner + .serialize_tuple_variant(name, variant_index, variant, len) + } + + fn serialize_map(self, len: Option) -> Result { + self.inner.serialize_map(len) + } + + fn serialize_struct( + self, + name: &'static str, + len: usize, + ) -> Result { + match self.inner.serialize_struct(name, len) { + Ok(s) => Ok(Self::SerializeStruct::new(s)), + Err(e) => Err(e), + } + } + + fn serialize_struct_variant( + self, + name: &'static str, + variant_index: u32, + variant: &'static str, + len: usize, + ) -> Result { + self.inner + .serialize_struct_variant(name, variant_index, variant, len) + } +} + +pub struct HexSerializeStruct +where + S: SerializeStruct, +{ + inner: S, +} + +impl HexSerializeStruct +where + S: SerializeStruct, +{ + pub fn new(inner: S) -> Self { + Self { inner } + } +} + +impl SerializeStruct for HexSerializeStruct +where + S: SerializeStruct, +{ + type Ok = S::Ok; + type Error = S::Error; + + fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error> + where + T: ?Sized + Serialize, + { + // Finally, here's the hack. Serialize the value, and try to deserialize + // it as a Vec. If that works, hex encode the Vec, otherwise use + // the default serialization. + // Unfortunately there's no way to inspect the generic type parameter T + // here, otherwise this logic would work by simply checking whether the + // generic type parameter T is a Vec or not. + let as_vec = match serde_json::to_vec(value) { + Ok(as_vec) => as_vec, + Err(_) => return self.inner.serialize_field(key, value), + }; + let val: Vec = match serde_json::from_slice(&as_vec) { + Ok(val) => val, + Err(_) => return self.inner.serialize_field(key, value), + }; + self.inner.serialize_field(key, &hex::encode(&val)) + } + + fn end(self) -> Result { + self.inner.end() + } +} + +pub mod value { + use std::fmt::Display; + + use serde::{ser::Impossible, Serialize}; + use serde_json::{Error, Map, Result, Value}; + + pub fn to_value(value: T) -> Result + where + T: Serialize, + { + value.serialize(Serializer) + } + + pub struct Serializer; + + impl serde::Serializer for Serializer { + type Ok = Value; + type Error = Error; + + type SerializeSeq = SerializeVec; + type SerializeTuple = SerializeVec; + type SerializeTupleStruct = SerializeVec; + type SerializeTupleVariant = SerializeTupleVariant; + type SerializeMap = SerializeMap; + type SerializeStruct = SerializeMap; + type SerializeStructVariant = SerializeStructVariant; + + #[inline] + fn serialize_bool(self, value: bool) -> Result { + Ok(Value::Bool(value)) + } + + #[inline] + fn serialize_i8(self, value: i8) -> Result { + self.serialize_i64(value as i64) + } + + #[inline] + fn serialize_i16(self, value: i16) -> Result { + self.serialize_i64(value as i64) + } + + #[inline] + fn serialize_i32(self, value: i32) -> Result { + self.serialize_i64(value as i64) + } + + fn serialize_i64(self, value: i64) -> Result { + Ok(Value::Number(value.into())) + } + + fn serialize_i128(self, value: i128) -> Result { + if let Ok(value) = i64::try_from(value) { + Ok(Value::Number(value.into())) + } else { + Err(serde::ser::Error::custom("number out of range")) + } + } + + #[inline] + fn serialize_u8(self, value: u8) -> Result { + self.serialize_u64(value as u64) + } + + #[inline] + fn serialize_u16(self, value: u16) -> Result { + self.serialize_u64(value as u64) + } + + #[inline] + fn serialize_u32(self, value: u32) -> Result { + self.serialize_u64(value as u64) + } + + #[inline] + fn serialize_u64(self, value: u64) -> Result { + Ok(Value::Number(value.into())) + } + + fn serialize_u128(self, value: u128) -> Result { + if let Ok(value) = u64::try_from(value) { + Ok(Value::Number(value.into())) + } else { + Err(serde::ser::Error::custom("number out of range")) + } + } + + #[inline] + fn serialize_f32(self, float: f32) -> Result { + Ok(Value::from(float)) + } + + #[inline] + fn serialize_f64(self, float: f64) -> Result { + Ok(Value::from(float)) + } + + #[inline] + fn serialize_char(self, value: char) -> Result { + let mut s = String::new(); + s.push(value); + Ok(Value::String(s)) + } + + #[inline] + fn serialize_str(self, value: &str) -> Result { + Ok(Value::String(value.to_owned())) + } + + fn serialize_bytes(self, value: &[u8]) -> Result { + Ok(Value::String(hex::encode(value))) + } + + #[inline] + fn serialize_unit(self) -> Result { + Ok(Value::Null) + } + + #[inline] + fn serialize_unit_struct(self, _name: &'static str) -> Result { + self.serialize_unit() + } + + #[inline] + fn serialize_unit_variant( + self, + _name: &'static str, + _variant_index: u32, + variant: &'static str, + ) -> Result { + self.serialize_str(variant) + } + + #[inline] + fn serialize_newtype_struct(self, _name: &'static str, value: &T) -> Result + where + T: ?Sized + Serialize, + { + value.serialize(self) + } + + fn serialize_newtype_variant( + self, + _name: &'static str, + _variant_index: u32, + variant: &'static str, + value: &T, + ) -> Result + where + T: ?Sized + Serialize, + { + let mut values = Map::new(); + values.insert(String::from(variant), to_value(value)?); + Ok(Value::Object(values)) + } + + #[inline] + fn serialize_none(self) -> Result { + self.serialize_unit() + } + + #[inline] + fn serialize_some(self, value: &T) -> Result + where + T: ?Sized + Serialize, + { + value.serialize(self) + } + + fn serialize_seq(self, len: Option) -> Result { + Ok(SerializeVec { + vec: Vec::with_capacity(len.unwrap_or(0)), + }) + } + + fn serialize_tuple(self, len: usize) -> Result { + self.serialize_seq(Some(len)) + } + + fn serialize_tuple_struct( + self, + _name: &'static str, + len: usize, + ) -> Result { + self.serialize_seq(Some(len)) + } + + fn serialize_tuple_variant( + self, + _name: &'static str, + _variant_index: u32, + variant: &'static str, + len: usize, + ) -> Result { + Ok(SerializeTupleVariant { + name: String::from(variant), + vec: Vec::with_capacity(len), + }) + } + + fn serialize_map(self, _len: Option) -> Result { + Ok(SerializeMap { + map: Map::new(), + next_key: None, + }) + } + + fn serialize_struct( + self, + _name: &'static str, + len: usize, + ) -> Result { + self.serialize_map(Some(len)) + } + + fn serialize_struct_variant( + self, + _name: &'static str, + _variant_index: u32, + variant: &'static str, + _len: usize, + ) -> Result { + Ok(SerializeStructVariant { + name: String::from(variant), + map: Map::new(), + }) + } + + fn collect_str(self, value: &T) -> Result + where + T: ?Sized + Display, + { + Ok(Value::String(value.to_string())) + } + } + + pub struct SerializeVec { + vec: Vec, + } + + pub struct SerializeTupleVariant { + name: String, + vec: Vec, + } + + pub struct SerializeMap { + map: Map, + next_key: Option, + } + + pub struct SerializeStructVariant { + name: String, + map: Map, + } + + impl serde::ser::SerializeSeq for SerializeVec { + type Ok = Value; + type Error = Error; + + fn serialize_element(&mut self, value: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + self.vec.push(to_value(value)?); + Ok(()) + } + + fn end(self) -> Result { + Ok(Value::Array(self.vec)) + } + } + + impl serde::ser::SerializeTuple for SerializeVec { + type Ok = Value; + type Error = Error; + + fn serialize_element(&mut self, value: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + serde::ser::SerializeSeq::serialize_element(self, value) + } + + fn end(self) -> Result { + serde::ser::SerializeSeq::end(self) + } + } + + impl serde::ser::SerializeTupleStruct for SerializeVec { + type Ok = Value; + type Error = Error; + + fn serialize_field(&mut self, value: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + serde::ser::SerializeSeq::serialize_element(self, value) + } + + fn end(self) -> Result { + serde::ser::SerializeSeq::end(self) + } + } + + impl serde::ser::SerializeTupleVariant for SerializeTupleVariant { + type Ok = Value; + type Error = Error; + + fn serialize_field(&mut self, value: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + self.vec.push(to_value(value)?); + Ok(()) + } + + fn end(self) -> Result { + let mut object = Map::new(); + + object.insert(self.name, Value::Array(self.vec)); + + Ok(Value::Object(object)) + } + } + + impl serde::ser::SerializeMap for SerializeMap { + type Ok = Value; + type Error = Error; + + fn serialize_key(&mut self, key: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + self.next_key = Some(key.serialize(MapKeySerializer)?); + Ok(()) + } + + fn serialize_value(&mut self, value: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + let key = self.next_key.take(); + // Panic because this indicates a bug in the program rather than an + // expected failure. + let key = key.expect("serialize_value called before serialize_key"); + + // Finally, here's the hack. Serialize the value, and try to deserialize + // it as a Vec. If that works, hex encode the Vec, otherwise use + // the default serialization. + // Unfortunately there's no way to inspect the generic type parameter T + // here, otherwise this logic would work by simply checking whether the + // generic type parameter T is a Vec or not. + let as_vec = match serde_json::to_vec(value) { + Ok(as_vec) => as_vec, + Err(_) => { + self.map.insert(key, to_value(value)?); + return Ok(()); + } + }; + let val: Vec = match serde_json::from_slice(&as_vec) { + Ok(val) => val, + Err(_) => { + self.map.insert(key, to_value(value)?); + return Ok(()); + } + }; + + self.map.insert(key, to_value(hex::encode(&val))?); + Ok(()) + } + + fn end(self) -> Result { + Ok(Value::Object(self.map)) + } + } + + impl serde::ser::SerializeStruct for SerializeMap { + type Ok = Value; + type Error = Error; + + fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + serde::ser::SerializeMap::serialize_entry(self, key, value) + } + + fn end(self) -> Result { + serde::ser::SerializeMap::end(self) + } + } + + impl serde::ser::SerializeStructVariant for SerializeStructVariant { + type Ok = Value; + type Error = Error; + + fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + self.map.insert(String::from(key), to_value(value)?); + Ok(()) + } + + fn end(self) -> Result { + let mut object = Map::new(); + + object.insert(self.name, Value::Object(self.map)); + + Ok(Value::Object(object)) + } + } + + struct MapKeySerializer; + + fn key_must_be_a_string() -> Error { + serde::ser::Error::custom("key must be a string") + } + + fn float_key_must_be_finite() -> Error { + serde::ser::Error::custom("float key must be finite") + } + + impl serde::Serializer for MapKeySerializer { + type Ok = String; + type Error = Error; + + type SerializeSeq = Impossible; + type SerializeTuple = Impossible; + type SerializeTupleStruct = Impossible; + type SerializeTupleVariant = Impossible; + type SerializeMap = Impossible; + type SerializeStruct = Impossible; + type SerializeStructVariant = Impossible; + + #[inline] + fn serialize_unit_variant( + self, + _name: &'static str, + _variant_index: u32, + variant: &'static str, + ) -> Result { + Ok(variant.to_owned()) + } + + #[inline] + fn serialize_newtype_struct(self, _name: &'static str, value: &T) -> Result + where + T: ?Sized + Serialize, + { + value.serialize(self) + } + + fn serialize_bool(self, value: bool) -> Result { + Ok(value.to_string()) + } + + fn serialize_i8(self, value: i8) -> Result { + Ok(value.to_string()) + } + + fn serialize_i16(self, value: i16) -> Result { + Ok(value.to_string()) + } + + fn serialize_i32(self, value: i32) -> Result { + Ok(value.to_string()) + } + + fn serialize_i64(self, value: i64) -> Result { + Ok(value.to_string()) + } + + fn serialize_i128(self, value: i128) -> Result { + Ok(value.to_string()) + } + + fn serialize_u8(self, value: u8) -> Result { + Ok(value.to_string()) + } + + fn serialize_u16(self, value: u16) -> Result { + Ok(value.to_string()) + } + + fn serialize_u32(self, value: u32) -> Result { + Ok(value.to_string()) + } + + fn serialize_u64(self, value: u64) -> Result { + Ok(value.to_string()) + } + + fn serialize_u128(self, value: u128) -> Result { + Ok(value.to_string()) + } + + fn serialize_f32(self, value: f32) -> Result { + if value.is_finite() { + Ok(ryu::Buffer::new().format_finite(value).to_owned()) + } else { + Err(float_key_must_be_finite()) + } + } + + fn serialize_f64(self, value: f64) -> Result { + if value.is_finite() { + Ok(ryu::Buffer::new().format_finite(value).to_owned()) + } else { + Err(float_key_must_be_finite()) + } + } + + #[inline] + fn serialize_char(self, value: char) -> Result { + Ok({ + let mut s = String::new(); + s.push(value); + s + }) + } + + #[inline] + fn serialize_str(self, value: &str) -> Result { + Ok(value.to_owned()) + } + + fn serialize_bytes(self, _value: &[u8]) -> Result { + Err(key_must_be_a_string()) + } + + fn serialize_unit(self) -> Result { + Err(key_must_be_a_string()) + } + + fn serialize_unit_struct(self, _name: &'static str) -> Result { + Err(key_must_be_a_string()) + } + + fn serialize_newtype_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _value: &T, + ) -> Result + where + T: ?Sized + Serialize, + { + Err(key_must_be_a_string()) + } + + fn serialize_none(self) -> Result { + Err(key_must_be_a_string()) + } + + fn serialize_some(self, _value: &T) -> Result + where + T: ?Sized + Serialize, + { + Err(key_must_be_a_string()) + } + + fn serialize_seq(self, _len: Option) -> Result { + Err(key_must_be_a_string()) + } + + fn serialize_tuple(self, _len: usize) -> Result { + Err(key_must_be_a_string()) + } + + fn serialize_tuple_struct( + self, + _name: &'static str, + _len: usize, + ) -> Result { + Err(key_must_be_a_string()) + } + + fn serialize_tuple_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result { + Err(key_must_be_a_string()) + } + + fn serialize_map(self, _len: Option) -> Result { + Err(key_must_be_a_string()) + } + + fn serialize_struct( + self, + _name: &'static str, + _len: usize, + ) -> Result { + Err(key_must_be_a_string()) + } + + fn serialize_struct_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result { + Err(key_must_be_a_string()) + } + + fn collect_str(self, value: &T) -> Result + where + T: ?Sized + Display, + { + Ok(value.to_string()) + } + } +} diff --git a/tools/sdk-cli/Cargo.lock b/tools/sdk-cli/Cargo.lock index b9cd3423a..0cba2204d 100644 --- a/tools/sdk-cli/Cargo.lock +++ b/tools/sdk-cli/Cargo.lock @@ -556,6 +556,7 @@ dependencies = [ "ripemd", "rusqlite", "rusqlite_migration", + "ryu", "sdk-common", "serde", "serde_json", @@ -2944,9 +2945,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.13" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "schannel"