Made SerdeDecoder attempt to allocate a string before complaining about being able to decode borrowed data (#475)
This commit is contained in:
parent
c1e9828e7d
commit
f3c21f2245
|
|
@ -45,6 +45,8 @@ serde_json = "1.0.68"
|
||||||
tempfile = "3.2.0"
|
tempfile = "3.2.0"
|
||||||
criterion = "0.3"
|
criterion = "0.3"
|
||||||
rand = "0.8"
|
rand = "0.8"
|
||||||
|
uuid = { version = "0.8", features = ["serde"] }
|
||||||
|
chrono = { version = "0.4", features = ["serde"] }
|
||||||
|
|
||||||
[[bench]]
|
[[bench]]
|
||||||
name = "varint"
|
name = "varint"
|
||||||
|
|
|
||||||
|
|
@ -121,7 +121,16 @@ impl<'a, 'de, DE: Decoder> Deserializer<'de> for SerdeDecoder<'a, DE> {
|
||||||
visitor.visit_char(Decode::decode(&mut self.de)?)
|
visitor.visit_char(Decode::decode(&mut self.de)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_str<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
|
#[cfg(feature = "alloc")]
|
||||||
|
fn deserialize_str<V>(mut self, visitor: V) -> Result<V::Value, Self::Error>
|
||||||
|
where
|
||||||
|
V: serde_incl::de::Visitor<'de>,
|
||||||
|
{
|
||||||
|
visitor.visit_string(Decode::decode(&mut self.de)?)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "alloc"))]
|
||||||
|
fn deserialize_str<V>(mut self, visitor: V) -> Result<V::Value, Self::Error>
|
||||||
where
|
where
|
||||||
V: serde_incl::de::Visitor<'de>,
|
V: serde_incl::de::Visitor<'de>,
|
||||||
{
|
{
|
||||||
|
|
@ -135,6 +144,15 @@ impl<'a, 'de, DE: Decoder> Deserializer<'de> for SerdeDecoder<'a, DE> {
|
||||||
visitor.visit_string(Decode::decode(&mut self.de)?)
|
visitor.visit_string(Decode::decode(&mut self.de)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "alloc")]
|
||||||
|
fn deserialize_bytes<V>(mut self, visitor: V) -> Result<V::Value, Self::Error>
|
||||||
|
where
|
||||||
|
V: serde_incl::de::Visitor<'de>,
|
||||||
|
{
|
||||||
|
visitor.visit_byte_buf(Decode::decode(&mut self.de)?)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "alloc"))]
|
||||||
fn deserialize_bytes<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
|
fn deserialize_bytes<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
|
||||||
where
|
where
|
||||||
V: serde_incl::de::Visitor<'de>,
|
V: serde_incl::de::Visitor<'de>,
|
||||||
|
|
|
||||||
|
|
@ -11,3 +11,6 @@ mod issue_467;
|
||||||
|
|
||||||
#[path = "issues/issue_459.rs"]
|
#[path = "issues/issue_459.rs"]
|
||||||
mod issue_459;
|
mod issue_459;
|
||||||
|
|
||||||
|
#[path = "issues/issue_474.rs"]
|
||||||
|
mod issue_474;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,97 @@
|
||||||
|
#![cfg(all(feature = "serde", feature = "std"))]
|
||||||
|
|
||||||
|
extern crate std;
|
||||||
|
|
||||||
|
use bincode::config::Configuration;
|
||||||
|
use chrono::{DateTime, Utc};
|
||||||
|
use serde_incl::de::DeserializeOwned;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::prelude::rust_2021::*;
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
#[derive(serde_derive::Serialize, serde_derive::Deserialize, PartialEq, Debug)]
|
||||||
|
#[serde(crate = "serde_incl")]
|
||||||
|
pub struct MyStruct {
|
||||||
|
name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(serde_derive::Serialize, serde_derive::Deserialize, PartialEq, Debug)]
|
||||||
|
#[serde(crate = "serde_incl")]
|
||||||
|
pub struct CustomerTest {
|
||||||
|
pub id: Option<Uuid>,
|
||||||
|
pub email_address: Option<String>,
|
||||||
|
pub is_active: Option<bool>,
|
||||||
|
pub date_stamp: Option<DateTime<Utc>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test() {
|
||||||
|
let test = MyStruct {
|
||||||
|
name: "Test Value".into(),
|
||||||
|
};
|
||||||
|
let cache_id = Uuid::nil();
|
||||||
|
let cache = MemCache::default();
|
||||||
|
|
||||||
|
cache.set_data::<MyStruct>(&cache_id, &test, 5).unwrap();
|
||||||
|
let model = cache.get_data::<MyStruct>(&cache_id).unwrap();
|
||||||
|
assert_eq!(test, model);
|
||||||
|
|
||||||
|
let test = CustomerTest {
|
||||||
|
id: Some(Uuid::nil()),
|
||||||
|
email_address: Some("foo@bar".into()),
|
||||||
|
is_active: None,
|
||||||
|
date_stamp: Some(Utc::now()),
|
||||||
|
};
|
||||||
|
|
||||||
|
cache.set_data::<CustomerTest>(&cache_id, &test, 5).unwrap();
|
||||||
|
let model = cache.get_data::<CustomerTest>(&cache_id).unwrap();
|
||||||
|
assert_eq!(test, model);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
struct MemCache {
|
||||||
|
cache: std::sync::RwLock<HashMap<Uuid, CacheItem>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MemCache {
|
||||||
|
fn set_data<T>(
|
||||||
|
&self,
|
||||||
|
key: &Uuid,
|
||||||
|
cache_data: &T,
|
||||||
|
expire_seconds: i64,
|
||||||
|
) -> Result<(), bincode::error::EncodeError>
|
||||||
|
where
|
||||||
|
T: Send + Sync + serde_incl::Serialize,
|
||||||
|
{
|
||||||
|
let config = Configuration::standard();
|
||||||
|
let mut guard = self.cache.write().unwrap();
|
||||||
|
|
||||||
|
let encoded = bincode::serde::encode_to_vec(&cache_data, config)?;
|
||||||
|
let cache_item = CacheItem::new(encoded, expire_seconds);
|
||||||
|
|
||||||
|
guard.insert(key.clone(), cache_item);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_data<T>(&self, key: &Uuid) -> Result<T, bincode::error::DecodeError>
|
||||||
|
where
|
||||||
|
T: Send + Sync + DeserializeOwned,
|
||||||
|
{
|
||||||
|
let config = Configuration::standard();
|
||||||
|
let guard = self.cache.read().unwrap();
|
||||||
|
let cache_item = guard.get(key).unwrap();
|
||||||
|
let (decoded, _len): (T, usize) =
|
||||||
|
bincode::serde::decode_from_slice(&cache_item.payload[..], config)?;
|
||||||
|
Ok(decoded)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CacheItem {
|
||||||
|
payload: Vec<u8>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CacheItem {
|
||||||
|
fn new(payload: Vec<u8>, _expire_seconds: i64) -> Self {
|
||||||
|
Self { payload }
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue