Struct leptos_use::utils::JsonCodec
source · pub struct JsonCodec;
Expand description
A codec for storing JSON messages that relies on serde_json
to parse.
§Example
// Primitive types:
let (get, set, remove) = use_local_storage::<i32, JsonCodec>("my-key");
// Structs:
#[derive(Serialize, Deserialize, Clone, Default, PartialEq)]
pub struct MyState {
pub hello: String,
}
let (get, set, remove) = use_local_storage::<MyState, JsonCodec>("my-struct-key");
§Versioning
If the JSON decoder fails, the storage hook will return T::Default
dropping the stored JSON value. See Codec
for general information on codec versioning.
§Rely on serde
This codec uses serde_json
under the hood. A simple way to avoid complex versioning is to rely on serde’s field attributes such as serde(default)
and serde(rename = "...")
.
§String replacement
Previous versions of leptos-use offered a merge_defaults
fn to rewrite the encoded value. This is possible by wrapping the codec but should be avoided.
#[derive(Serialize, Deserialize, Clone, Default, PartialEq)]
pub struct MyState {
pub hello: String,
pub greeting: String,
}
#[derive(Clone, Default)]
pub struct MyStateCodec();
impl StringCodec<MyState> for MyStateCodec {
type Error = serde_json::Error;
fn encode(&self, val: &MyState) -> Result<String, Self::Error> {
serde_json::to_string(val)
}
fn decode(&self, stored_value: String) -> Result<MyState, Self::Error> {
let default_value = MyState::default();
let rewritten = if stored_value.contains(r#""greeting":"#) {
stored_value
} else {
// add "greeting": "Hello" to the string
stored_value.replace("}", &format!(r#""greeting": "{}"}}"#, default_value.greeting))
};
serde_json::from_str(&rewritten)
}
}
let (get, set, remove) = use_local_storage::<MyState, MyStateCodec>("my-struct-key");
§Transform a JsValue
A better alternative to string replacement might be to parse the JSON then transform the resulting JsValue
before decoding it to to your struct again.
#[derive(Serialize, Deserialize, Clone, Default, PartialEq)]
pub struct MyState {
pub hello: String,
pub greeting: String,
}
#[derive(Clone, Default)]
pub struct MyStateCodec();
impl StringCodec<MyState> for MyStateCodec {
type Error = serde_json::Error;
fn encode(&self, val: &MyState) -> Result<String, Self::Error> {
serde_json::to_string(val)
}
fn decode(&self, stored_value: String) -> Result<MyState, Self::Error> {
let mut val: serde_json::Value = serde_json::from_str(&stored_value)?;
// add "greeting": "Hello" to the object if it's missing
if let Some(obj) = val.as_object_mut() {
if !obj.contains_key("greeting") {
obj.insert("greeting".to_string(), json!("Hello"));
}
serde_json::from_value(val)
} else {
Ok(MyState::default())
}
}
}
let (get, set, remove) = use_local_storage::<MyState, MyStateCodec>("my-struct-key");
Trait Implementations§
source§impl PartialEq for JsonCodec
impl PartialEq for JsonCodec
source§impl<T: Serialize + DeserializeOwned> StringCodec<T> for JsonCodec
impl<T: Serialize + DeserializeOwned> StringCodec<T> for JsonCodec
impl Copy for JsonCodec
impl StructuralPartialEq for JsonCodec
Auto Trait Implementations§
impl Freeze for JsonCodec
impl RefUnwindSafe for JsonCodec
impl Send for JsonCodec
impl Sync for JsonCodec
impl Unpin for JsonCodec
impl UnwindSafe for JsonCodec
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
source§impl<T> Instrument for T
impl<T> Instrument for T
source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
source§impl<T> IntoEither for T
impl<T> IntoEither for T
source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
Converts
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moresource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
Converts
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read more