diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index e2c8ca1..8187b1c 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,6 +1,6 @@ # These are supported funding model platforms -github: [Synphonyte]# Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] +github: [Synphonyte] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] patreon: # Replace with a single Patreon username open_collective: # Replace with a single Open Collective username ko_fi: # Replace with a single Ko-fi username diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2cc0813..95f75d3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -30,13 +30,13 @@ jobs: - name: Check formatting run: cargo fmt --check - name: Clippy - run: cargo clippy --features prost,serde,docs,math --tests -- -D warnings + run: cargo clippy --features docs,math --tests -- -D warnings - name: Run tests (general) - run: cargo test --features math,docs,ssr,prost,json_serde,msgpack_serde,bincode_serde,base64 + run: cargo test --features math,docs,ssr - name: Run tests (axum) - run: cargo test --features math,docs,ssr,prost,json_serde,msgpack_serde,bincode_serde,base64,axum --doc use_cookie::use_cookie + run: cargo test --features math,docs,ssr,axum --doc use_cookie::use_cookie - name: Run tests (actix) - run: cargo test --features math,docs,ssr,prost,json_serde,msgpack_serde,bincode_serde,base64,actix --doc use_cookie::use_cookie + run: cargo test --features math,docs,ssr,actix --doc use_cookie::use_cookie #### mdbook - name: Install mdbook I diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 559a729..68ee5cf 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -23,10 +23,10 @@ jobs: - name: Check formatting run: cargo fmt --check - name: Clippy - run: cargo clippy --features prost,serde,docs,math --tests -- -D warnings + run: cargo clippy --features docs,math --tests -- -D warnings - name: Run tests (general) - run: cargo test --features math,docs,ssr,prost,json_serde,msgpack_serde,bincode_serde,base64 + run: cargo test --features math,docs,ssr - name: Run tests (axum) - run: cargo test --features math,docs,ssr,prost,json_serde,msgpack_serde,bincode_serde,base64,axum --doc use_cookie::use_cookie + run: cargo test --features math,docs,ssr,axum --doc use_cookie::use_cookie - name: Run tests (actix) - run: cargo test --features math,docs,ssr,prost,json_serde,msgpack_serde,bincode_serde,base64,actix --doc use_cookie::use_cookie + run: cargo test --features math,docs,ssr,actix --doc use_cookie::use_cookie diff --git a/Cargo.toml b/Cargo.toml index d7a8d19..49474ef 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,9 +15,8 @@ homepage = "https://leptos-use.rs" [dependencies] actix-web = { version = "4", optional = true, default-features = false } async-trait = "0.1" -base64 = { version = "0.21", optional = true } cfg-if = "1" -bincode = { version = "1", optional = true } +codee = "0.1" cookie = { version = "0.18", features = ["percent-encode"] } default-struct-builder = "0.5" futures-util = "0.3" @@ -33,10 +32,6 @@ leptos_actix = { version = "0.6", optional = true } leptos-spin = { version = "0.1", optional = true } num = { version = "0.4", optional = true } paste = "1" -prost = { version = "0.12", optional = true } -rmp-serde = { version = "1.1", optional = true } -serde = { version = "1", optional = true } -serde_json = { version = "1", optional = true } thiserror = "1" wasm-bindgen = "0.2.92" wasm-bindgen-futures = "0.4" @@ -136,19 +131,19 @@ features = [ getrandom = { version = "0.2", features = ["js"] } leptos_meta = "0.6" rand = "0.8" +codee = { version = "0.1", features = ["json_serde", "msgpack_serde", "base64", "prost"] } +serde = { version = "1", features = ["derive"] } [features] actix = ["dep:actix-web", "dep:leptos_actix", "dep:http0_2"] axum = ["dep:leptos_axum", "dep:http1"] docs = [] math = ["num"] -prost = ["dep:prost"] -json_serde = ["dep:serde_json", "dep:serde"] spin = ["dep:leptos-spin", "dep:http1"] ssr = [] -msgpack_serde = ["dep:rmp-serde", "dep:serde"] -bincode_serde = ["dep:bincode", "dep:serde"] wasm_ssr = [] [package.metadata.docs.rs] -features = ["math", "docs", "ssr", "prost", "json_serde", "msgpack_serde", "bincode_serde"] +features = ["math", "docs", "ssr"] +rustdoc-args = ["--cfg=web_sys_unstable_apis"] +rustc-args = ["--cfg=web_sys_unstable_apis"] \ No newline at end of file diff --git a/docs/book/src/SUMMARY.md b/docs/book/src/SUMMARY.md index d43fb8a..5c32d80 100644 --- a/docs/book/src/SUMMARY.md +++ b/docs/book/src/SUMMARY.md @@ -2,6 +2,7 @@ [Introduction](introduction.md) [Get Started](get_started.md) +[Options](options.md) [Element Parameters](element_parameters.md) [Server-Side Rendering](server_side_rendering.md) [Encoding and Decoding Data](codecs.md) diff --git a/docs/book/src/options.md b/docs/book/src/options.md new file mode 100644 index 0000000..fe312ca --- /dev/null +++ b/docs/book/src/options.md @@ -0,0 +1,22 @@ +# Options + +Most functions in Leptos-Use come with a version `..._with_options`. For example `use_css_var` has a +version `use_css_var_with_options`. As the name suggests, you can provide additional options to those versions of the +functions. + +These options are defined as structs with the corresponding PascalCase name. For our example `use_css_var_with_options` +the name of the struct is `UseCssVarOptions`. Every option struct implements `Default` and the builder pattern to +make it easy to change only the values needed. This can look like the following example. + +```rust +let (color, set_color) = use_css_var_with_options( + "--color", + UseCssVarOptions::default() + .target(el) + .initial_value("#eee"), +); +``` + +Here only the values `target` and `initial_value` are changed and everything else is left to default. + +TODO : automatic conversion like Fn and Option \ No newline at end of file diff --git a/examples/use_storage/Cargo.toml b/examples/use_storage/Cargo.toml index 98ebbf3..4a53065 100644 --- a/examples/use_storage/Cargo.toml +++ b/examples/use_storage/Cargo.toml @@ -4,11 +4,12 @@ version = "0.1.0" edition = "2021" [dependencies] +codee = { path = "../../../codee", features = ["json_serde"] } leptos = { version = "0.6", features = ["nightly", "csr"] } console_error_panic_hook = "0.1" console_log = "1" log = "0.4" -leptos-use = { path = "../..", features = ["docs", "json_serde"] } +leptos-use = { path = "../..", features = ["docs"] } web-sys = "0.3" serde = "1.0.163" diff --git a/examples/use_websocket/Cargo.toml b/examples/use_websocket/Cargo.toml index 76baa77..971690c 100644 --- a/examples/use_websocket/Cargo.toml +++ b/examples/use_websocket/Cargo.toml @@ -5,10 +5,11 @@ edition = "2021" [dependencies] leptos = { version = "0.6", features = ["nightly", "csr"] } +codee = { path = "../../../codee", features = ["msgpack_serde"] } console_error_panic_hook = "0.1" console_log = "1" log = "0.4" -leptos-use = { path = "../..", features = ["docs", "msgpack_serde"] } +leptos-use = { path = "../..", features = ["docs"] } serde = { version = "1", features = ["derive"] } web-sys = "0.3" diff --git a/examples/use_websocket/src/main.rs b/examples/use_websocket/src/main.rs index 7a5e370..477f3e2 100644 --- a/examples/use_websocket/src/main.rs +++ b/examples/use_websocket/src/main.rs @@ -6,7 +6,7 @@ use leptos_use::{ }; use serde::{Deserialize, Serialize}; -use leptos_use::utils::{FromToStringCodec, MsgpackSerdeCodec}; +use codee::{binary::MsgpackSerdeCodec, string::FromToStringCodec}; use web_sys::{CloseEvent, Event}; #[derive(Serialize, Deserialize, Debug)] diff --git a/src/storage/use_local_storage.rs b/src/storage/use_local_storage.rs index 24d3582..41811e6 100644 --- a/src/storage/use_local_storage.rs +++ b/src/storage/use_local_storage.rs @@ -1,5 +1,5 @@ use super::{use_storage_with_options, StorageType, UseStorageOptions}; -use crate::utils::{Decoder, Encoder}; +use codee::{Decoder, Encoder}; use leptos::signal_prelude::*; /// Reactive [LocalStorage](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage). diff --git a/src/storage/use_session_storage.rs b/src/storage/use_session_storage.rs index bb13cfe..b377edf 100644 --- a/src/storage/use_session_storage.rs +++ b/src/storage/use_session_storage.rs @@ -1,5 +1,5 @@ use super::{use_storage_with_options, StorageType, UseStorageOptions}; -use crate::utils::{Decoder, Encoder}; +use codee::{Decoder, Encoder}; use leptos::signal_prelude::*; /// Reactive [SessionStorage](https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage). diff --git a/src/storage/use_storage.rs b/src/storage/use_storage.rs index 1df4133..e98591e 100644 --- a/src/storage/use_storage.rs +++ b/src/storage/use_storage.rs @@ -1,8 +1,8 @@ -use crate::utils::{CodecError, Decoder, Encoder}; use crate::{ core::{MaybeRwSignal, StorageType}, utils::FilterOptions, }; +use codee::{CodecError, Decoder, Encoder}; use default_struct_builder::DefaultBuilder; use leptos::*; use std::rc::Rc; @@ -39,7 +39,8 @@ const INTERNAL_STORAGE_EVENT: &str = "leptos-use-storage"; /// # use leptos::*; /// # use leptos_use::storage::{StorageType, use_local_storage, use_session_storage, use_storage}; /// # use serde::{Deserialize, Serialize}; -/// # use leptos_use::utils::{FromToStringCodec, JsonSerdeCodec, ProstCodec, Base64}; +/// # use codee::string::{FromToStringCodec, JsonSerdeCodec, Base64}; +/// # use codee::binary::ProstCodec; /// # /// # #[component] /// # pub fn Demo() -> impl IntoView { @@ -94,7 +95,7 @@ const INTERNAL_STORAGE_EVENT: &str = "leptos-use-storage"; /// ``` /// # use leptos::*; /// # use leptos_use::storage::use_session_storage; -/// # use leptos_use::utils::FromToStringCodec; +/// # use codee::string::FromToStringCodec; /// # /// # #[component] /// # pub fn Example() -> impl IntoView { @@ -127,7 +128,7 @@ const INTERNAL_STORAGE_EVENT: &str = "leptos-use-storage"; /// ``` /// # use leptos::*; /// # use leptos_use::storage::{use_local_storage_with_options, UseStorageOptions}; -/// # use leptos_use::utils::FromToStringCodec; +/// # use codee::string::FromToStringCodec; /// # /// # #[component] /// # pub fn Example() -> impl IntoView { diff --git a/src/use_broadcast_channel.rs b/src/use_broadcast_channel.rs index 62cfac4..fe9d823 100644 --- a/src/use_broadcast_channel.rs +++ b/src/use_broadcast_channel.rs @@ -1,7 +1,7 @@ -use crate::utils::{CodecError, Decoder, Encoder}; use crate::{ js, use_event_listener, use_event_listener_with_options, use_supported, UseEventListenerOptions, }; +use codee::{CodecError, Decoder, Encoder}; use leptos::*; use thiserror::Error; use wasm_bindgen::JsValue; @@ -23,7 +23,7 @@ use wasm_bindgen::JsValue; /// ``` /// # use leptos::*; /// # use leptos_use::{use_broadcast_channel, UseBroadcastChannelReturn}; -/// # use leptos_use::utils::FromToStringCodec; +/// # use codee::string::FromToStringCodec; /// # /// # #[component] /// # fn Demo() -> impl IntoView { @@ -54,7 +54,7 @@ use wasm_bindgen::JsValue; /// # use leptos::*; /// # use serde::{Deserialize, Serialize}; /// # use leptos_use::use_broadcast_channel; -/// # use leptos_use::utils::JsonSerdeCodec; +/// # use codee::string::JsonSerdeCodec; /// # /// // Data sent in JSON must implement Serialize, Deserialize: /// #[derive(Serialize, Deserialize, Clone, PartialEq)] diff --git a/src/use_color_mode.rs b/src/use_color_mode.rs index af35e7f..5e0ba98 100644 --- a/src/use_color_mode.rs +++ b/src/use_color_mode.rs @@ -2,8 +2,8 @@ use crate::core::url; use crate::core::StorageType; use crate::core::{ElementMaybeSignal, MaybeRwSignal}; use crate::storage::{use_storage_with_options, UseStorageOptions}; -use crate::utils::FromToStringCodec; use crate::{sync_signal_with_options, use_cookie, use_preferred_dark, SyncSignalOptions}; +use codee::string::FromToStringCodec; use default_struct_builder::DefaultBuilder; use leptos::*; use std::fmt::{Display, Formatter}; diff --git a/src/use_cookie.rs b/src/use_cookie.rs index e2d6aaf..6f53d8e 100644 --- a/src/use_cookie.rs +++ b/src/use_cookie.rs @@ -1,7 +1,7 @@ #![allow(clippy::too_many_arguments)] use crate::core::now; -use crate::utils::{CodecError, Decoder, Encoder}; +use codee::{CodecError, Decoder, Encoder}; use cookie::time::{Duration, OffsetDateTime}; pub use cookie::SameSite; use cookie::{Cookie, CookieJar}; @@ -30,7 +30,7 @@ use std::rc::Rc; /// ``` /// # use leptos::*; /// # use leptos_use::use_cookie; -/// # use leptos_use::utils::FromToStringCodec; +/// # use codee::string::FromToStringCodec; /// # use rand::prelude::*; /// /// # @@ -70,7 +70,7 @@ use std::rc::Rc; /// # use cookie::SameSite; /// # use leptos::*; /// # use leptos_use::{use_cookie_with_options, UseCookieOptions}; -/// # use leptos_use::utils::FromToStringCodec; +/// # use codee::string::FromToStringCodec; /// # /// # #[component] /// # fn Demo() -> impl IntoView { @@ -105,7 +105,7 @@ use std::rc::Rc; /// # use leptos::*; /// # use serde::{Deserialize, Serialize}; /// # use leptos_use::{use_cookie_with_options, UseCookieOptions}; -/// # use leptos_use::utils::JsonSerdeCodec; +/// # use codee::string::JsonSerdeCodec; /// # /// # #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] /// # pub struct Auth { @@ -215,10 +215,10 @@ where #[cfg(not(feature = "ssr"))] { - use crate::utils::{FromToStringCodec, OptionCodec}; use crate::{ use_broadcast_channel, watch_pausable, UseBroadcastChannelReturn, WatchPausableReturn, }; + use codee::string::{FromToStringCodec, OptionCodec}; let UseBroadcastChannelReturn { message, post, .. } = use_broadcast_channel::, OptionCodec>(&format!( diff --git a/src/use_event_source.rs b/src/use_event_source.rs index fe7dcaa..e158324 100644 --- a/src/use_event_source.rs +++ b/src/use_event_source.rs @@ -1,6 +1,6 @@ use crate::core::ConnectionReadyState; -use crate::utils::Decoder; use crate::{js, use_event_listener, ReconnectLimit}; +use codee::Decoder; use default_struct_builder::DefaultBuilder; use leptos::*; use std::cell::Cell; @@ -27,7 +27,8 @@ use thiserror::Error; /// /// ``` /// # use leptos::*; -/// # use leptos_use::{use_event_source, UseEventSourceReturn, utils::JsonSerdeCodec}; +/// # use leptos_use::{use_event_source, UseEventSourceReturn}; +/// # use codee::string::JsonSerdeCodec; /// # use serde::{Deserialize, Serialize}; /// # /// #[derive(Serialize, Deserialize, Clone, PartialEq)] @@ -56,7 +57,8 @@ use thiserror::Error; /// /// ``` /// # use leptos::*; -/// # use leptos_use::{use_event_source_with_options, UseEventSourceReturn, UseEventSourceOptions, utils::FromToStringCodec}; +/// # use leptos_use::{use_event_source_with_options, UseEventSourceReturn, UseEventSourceOptions}; +/// # use codee::string::FromToStringCodec; /// # /// # #[component] /// # fn Demo() -> impl IntoView { @@ -87,7 +89,8 @@ use thiserror::Error; /// /// ``` /// # use leptos::*; -/// # use leptos_use::{use_event_source_with_options, UseEventSourceReturn, UseEventSourceOptions, utils::FromToStringCodec, ReconnectLimit}; +/// # use leptos_use::{use_event_source_with_options, UseEventSourceReturn, UseEventSourceOptions, ReconnectLimit}; +/// # use codee::string::FromToStringCodec; /// # /// # #[component] /// # fn Demo() -> impl IntoView { diff --git a/src/use_websocket.rs b/src/use_websocket.rs index 79f022b..d7c41e4 100644 --- a/src/use_websocket.rs +++ b/src/use_websocket.rs @@ -8,7 +8,7 @@ use std::time::Duration; use thiserror::Error; use crate::core::ConnectionReadyState; -use crate::utils::{ +use codee::{ CodecError, Decoder, Encoder, HybridCoderError, HybridDecoder, HybridEncoder, IsBinary, }; use default_struct_builder::DefaultBuilder; @@ -31,7 +31,7 @@ use web_sys::{BinaryType, CloseEvent, Event, MessageEvent, WebSocket}; /// /// ``` /// # use leptos::*; -/// # use leptos_use::utils::FromToStringCodec; +/// # use codee::string::FromToStringCodec; /// # use leptos_use::{use_websocket, UseWebSocketReturn}; /// # use leptos_use::core::ConnectionReadyState; /// # @@ -81,7 +81,7 @@ use web_sys::{BinaryType, CloseEvent, Event, MessageEvent, WebSocket}; /// /// ``` /// # use leptos::*; -/// # use leptos_use::utils::MsgpackSerdeCodec; +/// # use codee::binary::MsgpackSerdeCodec; /// # use leptos_use::{use_websocket, UseWebSocketReturn}; /// # use serde::{Deserialize, Serialize}; /// # @@ -164,7 +164,7 @@ use web_sys::{BinaryType, CloseEvent, Event, MessageEvent, WebSocket}; /// /// ``` /// # use leptos::*; -/// # use leptos_use::utils::FromToStringCodec; +/// # use codee::string::FromToStringCodec; /// # use leptos_use::{use_websocket, UseWebSocketReturn}; /// # use std::rc::Rc; /// # #[derive(Clone)] diff --git a/src/utils/codecs/bin/bincode_serde.rs b/src/utils/codecs/bin/bincode_serde.rs deleted file mode 100644 index db1e309..0000000 --- a/src/utils/codecs/bin/bincode_serde.rs +++ /dev/null @@ -1,45 +0,0 @@ -use crate::utils::{Decoder, Encoder}; - -/// A codec that relies on `bincode` adn `serde` to encode data in the bincode format. -/// -/// This is only available with the **`bincode` feature** enabled. -pub struct BincodeSerdeCodec; - -impl Encoder for BincodeSerdeCodec { - type Error = bincode::Error; - type Encoded = Vec; - - fn encode(val: &T) -> Result { - bincode::serialize(val) - } -} - -impl Decoder for BincodeSerdeCodec { - type Error = bincode::Error; - type Encoded = [u8]; - - fn decode(val: &Self::Encoded) -> Result { - bincode::deserialize(val) - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_bincode_codec() { - #[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)] - struct Test { - s: String, - i: i32, - } - let t = Test { - s: String::from("party time 🎉"), - i: 42, - }; - let enc = BincodeSerdeCodec::encode(&t).unwrap(); - let dec: Test = BincodeSerdeCodec::decode(&enc).unwrap(); - assert_eq!(dec, t); - } -} diff --git a/src/utils/codecs/bin/from_to_bytes.rs b/src/utils/codecs/bin/from_to_bytes.rs deleted file mode 100644 index 9ef9bc8..0000000 --- a/src/utils/codecs/bin/from_to_bytes.rs +++ /dev/null @@ -1,112 +0,0 @@ -use crate::utils::{Decoder, Encoder}; -use thiserror::Error; - -/// A binary codec that uses rust own binary encoding functions to encode and decode data. -/// This can be used if you want to encode only primitives and don't want to rely on third party -/// crates like `bincode` or `rmp-serde`. If you have more complex data check out -/// [`BincodeSerdeCodec`] or [`MsgpackSerdeCodec`]. -pub struct FromToBytesCodec; - -#[derive(Error, Debug)] -pub enum FromToBytesCodecError { - #[error("failed to convert byte slice to byte array")] - InvalidByteSlice(#[from] std::array::TryFromSliceError), - - #[error("failed to convert byte array to string")] - InvalidString(#[from] std::string::FromUtf8Error), -} - -macro_rules! impl_bin_codec_for_number { - ($num:ty) => { - impl Encoder<$num> for FromToBytesCodec { - type Error = (); - type Encoded = Vec; - - fn encode(val: &$num) -> Result { - Ok(val.to_be_bytes().to_vec()) - } - } - - impl Decoder<$num> for FromToBytesCodec { - type Error = FromToBytesCodecError; - type Encoded = [u8]; - - fn decode(val: &Self::Encoded) -> Result<$num, Self::Error> { - Ok(<$num>::from_be_bytes(val.try_into()?)) - } - } - }; -} - -impl_bin_codec_for_number!(i8); -impl_bin_codec_for_number!(u8); - -impl_bin_codec_for_number!(i16); -impl_bin_codec_for_number!(u16); - -impl_bin_codec_for_number!(i32); -impl_bin_codec_for_number!(u32); - -impl_bin_codec_for_number!(i64); -impl_bin_codec_for_number!(u64); - -impl_bin_codec_for_number!(i128); -impl_bin_codec_for_number!(u128); - -impl_bin_codec_for_number!(isize); -impl_bin_codec_for_number!(usize); - -impl_bin_codec_for_number!(f32); -impl_bin_codec_for_number!(f64); - -impl Encoder for FromToBytesCodec { - type Error = (); - type Encoded = Vec; - - fn encode(val: &bool) -> Result { - let num: u8 = if *val { 1 } else { 0 }; - Self::encode(&num) - } -} - -impl Decoder for FromToBytesCodec { - type Error = FromToBytesCodecError; - type Encoded = [u8]; - - fn decode(val: &Self::Encoded) -> Result { - let num: u8 = Self::decode(val)?; - Ok(num != 0) - } -} - -impl Encoder for FromToBytesCodec { - type Error = (); - type Encoded = Vec; - - fn encode(val: &String) -> Result { - Ok(val.as_bytes().to_vec()) - } -} - -impl Decoder for FromToBytesCodec { - type Error = FromToBytesCodecError; - type Encoded = [u8]; - - fn decode(val: &Self::Encoded) -> Result { - Ok(String::from_utf8(val.to_vec())?) - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_fromtobytes_codec() { - let t = 50; - - let enc: Vec = FromToBytesCodec::encode(&t).unwrap(); - let dec: i32 = FromToBytesCodec::decode(enc.as_slice()).unwrap(); - assert_eq!(dec, t); - } -} diff --git a/src/utils/codecs/bin/mod.rs b/src/utils/codecs/bin/mod.rs deleted file mode 100644 index 8698906..0000000 --- a/src/utils/codecs/bin/mod.rs +++ /dev/null @@ -1,16 +0,0 @@ -#[cfg(feature = "bincode_serde")] -mod bincode_serde; -mod from_to_bytes; -#[cfg(feature = "msgpack_serde")] -mod msgpack_serde; -#[cfg(feature = "prost")] -mod prost; - -#[cfg(feature = "bincode_serde")] -pub use bincode_serde::*; -#[allow(unused_imports)] -pub use from_to_bytes::*; -#[cfg(feature = "msgpack_serde")] -pub use msgpack_serde::*; -#[cfg(feature = "prost")] -pub use prost::*; diff --git a/src/utils/codecs/bin/msgpack_serde.rs b/src/utils/codecs/bin/msgpack_serde.rs deleted file mode 100644 index 77778c8..0000000 --- a/src/utils/codecs/bin/msgpack_serde.rs +++ /dev/null @@ -1,45 +0,0 @@ -use crate::utils::{Decoder, Encoder}; - -/// A codec that relies on `rmp-serde` to encode data in the msgpack format. -/// -/// This is only available with the **`msgpack` feature** enabled. -pub struct MsgpackSerdeCodec; - -impl Encoder for MsgpackSerdeCodec { - type Error = rmp_serde::encode::Error; - type Encoded = Vec; - - fn encode(val: &T) -> Result { - rmp_serde::to_vec(val) - } -} - -impl Decoder for MsgpackSerdeCodec { - type Error = rmp_serde::decode::Error; - type Encoded = [u8]; - - fn decode(val: &Self::Encoded) -> Result { - rmp_serde::from_slice(val) - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_msgpack_codec() { - #[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)] - struct Test { - s: String, - i: i32, - } - let t = Test { - s: String::from("party time 🎉"), - i: 42, - }; - let enc = MsgpackSerdeCodec::encode(&t).unwrap(); - let dec: Test = MsgpackSerdeCodec::decode(&enc).unwrap(); - assert_eq!(dec, t); - } -} diff --git a/src/utils/codecs/bin/prost.rs b/src/utils/codecs/bin/prost.rs deleted file mode 100644 index 850c190..0000000 --- a/src/utils/codecs/bin/prost.rs +++ /dev/null @@ -1,76 +0,0 @@ -use crate::utils::{Decoder, Encoder}; - -/// A codec for storing ProtoBuf messages that relies on [`prost`](https://github.com/tokio-rs/prost) to parse. -/// -/// [Protocol buffers](https://protobuf.dev/overview/) is a serialisation format useful for -/// long-term storage. It provides semantics for versioning that are not present in JSON or other -/// formats. [`prost`] is a Rust implementation of Protocol Buffers. -/// -/// This codec uses [`prost`](https://github.com/tokio-rs/prost) to encode the message into a byte stream. -/// To use it with local storage in the example below we wrap it with [`Base64`] to represent the bytes as a string. -/// -/// ## Example -/// ``` -/// # use leptos::*; -/// # use leptos_use::storage::{StorageType, use_local_storage, use_session_storage, use_storage, UseStorageOptions}; -/// # use leptos_use::utils::{Base64, ProstCodec}; -/// # -/// # pub fn Demo() -> impl IntoView { -/// // Primitive types: -/// let (get, set, remove) = use_local_storage::>("my-key"); -/// -/// // Structs: -/// #[derive(Clone, PartialEq, prost::Message)] -/// pub struct MyState { -/// #[prost(string, tag = "1")] -/// pub hello: String, -/// } -/// let (get, set, remove) = use_local_storage::>("my-struct-key"); -/// # view! { } -/// # } -/// ``` -/// -/// Note: we've defined and used the `prost` attribute here for brevity. Alternate usage would be to -/// describe the message in a .proto file and use [`prost_build`](https://docs.rs/prost-build) to -/// auto-generate the Rust code. -pub struct ProstCodec; - -impl Encoder for ProstCodec { - type Error = (); - type Encoded = Vec; - - fn encode(val: &T) -> Result { - let buf = val.encode_to_vec(); - Ok(buf) - } -} - -impl Decoder for ProstCodec { - type Error = prost::DecodeError; - type Encoded = [u8]; - - fn decode(val: &Self::Encoded) -> Result { - T::decode(val) - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_prost_codec() { - #[derive(Clone, PartialEq, prost::Message)] - struct Test { - #[prost(string, tag = "1")] - s: String, - #[prost(int32, tag = "2")] - i: i32, - } - let t = Test { - s: String::from("party time 🎉"), - i: 42, - }; - assert_eq!(ProstCodec::decode(&ProstCodec::encode(&t).unwrap()), Ok(t)); - } -} diff --git a/src/utils/codecs/hybrid.rs b/src/utils/codecs/hybrid.rs deleted file mode 100644 index 42ccdc8..0000000 --- a/src/utils/codecs/hybrid.rs +++ /dev/null @@ -1,108 +0,0 @@ -use crate::utils::{Decoder, Encoder}; -use thiserror::Error; - -pub trait IsBinary { - fn is_binary() -> bool; -} - -impl IsBinary for D -where - D: Decoder, -{ - fn is_binary() -> bool { - true - } -} - -impl IsBinary for D -where - D: Decoder, -{ - fn is_binary() -> bool { - false - } -} - -#[derive(Debug, Error)] -pub enum HybridCoderError { - #[error("Not implemented: {0}")] - NotImplemented(&'static str), - #[error("Decoding error")] - Coder(#[from] E), -} - -pub trait HybridDecoder { - type Error; - - fn decode_str(_val: &str) -> Result> { - Err(HybridCoderError::NotImplemented( - "You're trying to decode from a string. This codec is binary.", - )) - } - - fn decode_bin(_val: &[u8]) -> Result> { - Err(HybridCoderError::NotImplemented( - "You're trying to decode from a byte slice. This codec is a string codec.", - )) - } -} - -impl HybridDecoder for D -where - D: Decoder, -{ - type Error = D::Error; - - fn decode_bin(val: &[u8]) -> Result> { - Ok(D::decode(val)?) - } -} - -impl HybridDecoder for D -where - D: Decoder, -{ - type Error = D::Error; - - fn decode_str(val: &str) -> Result> { - Ok(D::decode(val)?) - } -} - -pub trait HybridEncoder { - type Error; - - fn encode_str(_val: &T) -> Result> { - Err(HybridCoderError::NotImplemented( - "You're trying to encode into a string. This codec is binary.", - )) - } - - fn encode_bin(_val: &T) -> Result, HybridCoderError> { - Err(HybridCoderError::NotImplemented( - "You're trying to encode into a byte vec. This codec is a string codec.", - )) - } -} - -impl HybridEncoder> for E -where - E: Encoder>, -{ - type Error = E::Error; - - fn encode_bin(val: &T) -> Result, HybridCoderError> { - Ok(E::encode(val)?) - } -} - -impl HybridEncoder for E -where - E: Encoder, -{ - type Error = E::Error; - - fn encode_str(val: &T) -> Result> { - Ok(E::encode(val)?) - } -} diff --git a/src/utils/codecs/mod.rs b/src/utils/codecs/mod.rs deleted file mode 100644 index 708ec1d..0000000 --- a/src/utils/codecs/mod.rs +++ /dev/null @@ -1,32 +0,0 @@ -mod bin; -mod hybrid; -mod string; - -pub use bin::*; -pub use hybrid::*; -pub use string::*; -use thiserror::Error; - -/// Trait every encoder must implement. -pub trait Encoder: 'static { - type Error; - type Encoded; - - fn encode(val: &T) -> Result; -} - -/// Trait every decoder must implement. -pub trait Decoder: 'static { - type Error; - type Encoded: ?Sized; - - fn decode(val: &Self::Encoded) -> Result; -} - -#[derive(Error, Debug)] -pub enum CodecError { - #[error("failed to encode: {0}")] - Encode(E), - #[error("failed to decode: {0}")] - Decode(D), -} diff --git a/src/utils/codecs/string/base64.rs b/src/utils/codecs/string/base64.rs deleted file mode 100644 index b9f0265..0000000 --- a/src/utils/codecs/string/base64.rs +++ /dev/null @@ -1,67 +0,0 @@ -use crate::utils::{Decoder, Encoder}; -use base64::Engine; -use thiserror::Error; - -/// Wraps a binary codec and make it a string codec by representing the binary data as a base64 -/// string. -/// -/// Only available with the **`base64` feature** enabled. -/// -/// Example: -/// -/// ``` -/// # use leptos_use::utils::{Base64, MsgpackSerdeCodec, Encoder, Decoder}; -/// # use serde::{Serialize, Deserialize}; -/// # -/// #[derive(Serialize, Deserialize, PartialEq, Debug)] -/// struct MyState { -/// chicken_count: u32, -/// egg_count: u32, -/// farm_name: String, -/// } -/// -/// let original_value = MyState { -/// chicken_count: 10, -/// egg_count: 20, -/// farm_name: "My Farm".to_owned(), -/// }; -/// -/// let encoded: String = Base64::::encode(&original_value).unwrap(); -/// let decoded: MyState = Base64::::decode(&encoded).unwrap(); -/// -/// assert_eq!(decoded, original_value); -/// ``` -pub struct Base64(C); - -#[derive(Error, Debug, PartialEq)] -pub enum Base64DecodeError { - #[error("failed to decode base64: {0}")] - DecodeBase64(#[from] base64::DecodeError), - #[error("failed to decode: {0}")] - Decoder(Err), -} - -impl Encoder for Base64 -where - E: Encoder>, -{ - type Error = E::Error; - type Encoded = String; - - fn encode(val: &T) -> Result { - Ok(base64::engine::general_purpose::STANDARD.encode(E::encode(val)?)) - } -} - -impl Decoder for Base64 -where - D: Decoder, -{ - type Error = Base64DecodeError; - type Encoded = str; - - fn decode(val: &Self::Encoded) -> Result { - let buf = base64::engine::general_purpose::STANDARD.decode(val)?; - D::decode(&buf).map_err(Base64DecodeError::Decoder) - } -} diff --git a/src/utils/codecs/string/from_to_string.rs b/src/utils/codecs/string/from_to_string.rs deleted file mode 100644 index 46ebca7..0000000 --- a/src/utils/codecs/string/from_to_string.rs +++ /dev/null @@ -1,51 +0,0 @@ -use crate::utils::{Decoder, Encoder}; -use std::str::FromStr; - -/// A string codec that relies on [`FromStr`] and [`ToString`]. It can encode anything that -/// implements [`ToString`] and decode anything that implements [`FromStr`]. -/// -/// This makes simple key / value easy to use for primitive types. It is also useful for encoding -/// simply data structures without depending on third party crates like serde and serde_json. -/// -/// ## Example -/// ``` -/// # use leptos::*; -/// # use leptos_use::storage::{StorageType, use_local_storage, use_session_storage, use_storage, UseStorageOptions}; -/// # use leptos_use::utils::FromToStringCodec; -/// # -/// # pub fn Demo() -> impl IntoView { -/// let (get, set, remove) = use_local_storage::("my-key"); -/// # view! { } -/// # } -/// ``` -pub struct FromToStringCodec; - -impl Encoder for FromToStringCodec { - type Error = (); - type Encoded = String; - - fn encode(val: &T) -> Result { - Ok(val.to_string()) - } -} - -impl Decoder for FromToStringCodec { - type Error = T::Err; - type Encoded = str; - - fn decode(val: &Self::Encoded) -> Result { - T::from_str(val) - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_string_codec() { - let s = String::from("party time 🎉"); - assert_eq!(FromToStringCodec::encode(&s), Ok(s.clone())); - assert_eq!(FromToStringCodec::decode(&s), Ok(s)); - } -} diff --git a/src/utils/codecs/string/json_serde.rs b/src/utils/codecs/string/json_serde.rs deleted file mode 100644 index c1b75a8..0000000 --- a/src/utils/codecs/string/json_serde.rs +++ /dev/null @@ -1,67 +0,0 @@ -use crate::utils::{Decoder, Encoder}; - -/// A codec for encoding JSON messages that relies on [`serde_json`]. -/// -/// Only available with the **`json` feature** enabled. -/// -/// ## Example -/// -/// ``` -/// # use leptos::*; -/// # use leptos_use::storage::{StorageType, use_local_storage, use_session_storage, use_storage, UseStorageOptions}; -/// # use serde::{Deserialize, Serialize}; -/// # use leptos_use::utils::JsonSerdeCodec; -/// # -/// # pub fn Demo() -> impl IntoView { -/// // Primitive types: -/// let (get, set, remove) = use_local_storage::("my-key"); -/// -/// // Structs: -/// #[derive(Serialize, Deserialize, Clone, Default, PartialEq)] -/// pub struct MyState { -/// pub hello: String, -/// } -/// let (get, set, remove) = use_local_storage::("my-struct-key"); -/// # view! { } -/// # } -/// ``` -pub struct JsonSerdeCodec; - -impl Encoder for JsonSerdeCodec { - type Error = serde_json::Error; - type Encoded = String; - - fn encode(val: &T) -> Result { - serde_json::to_string(val) - } -} - -impl Decoder for JsonSerdeCodec { - type Error = serde_json::Error; - type Encoded = str; - - fn decode(val: &Self::Encoded) -> Result { - serde_json::from_str(val) - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_json_codec() { - #[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)] - struct Test { - s: String, - i: i32, - } - let t = Test { - s: String::from("party time 🎉"), - i: 42, - }; - let enc = JsonSerdeCodec::encode(&t).unwrap(); - let dec: Test = JsonSerdeCodec::decode(&enc).unwrap(); - assert_eq!(dec, t); - } -} diff --git a/src/utils/codecs/string/mod.rs b/src/utils/codecs/string/mod.rs deleted file mode 100644 index dc251f2..0000000 --- a/src/utils/codecs/string/mod.rs +++ /dev/null @@ -1,13 +0,0 @@ -#[cfg(feature = "base64")] -mod base64; -mod from_to_string; -#[cfg(feature = "json_serde")] -mod json_serde; -mod option; - -#[cfg(feature = "base64")] -pub use base64::*; -pub use from_to_string::*; -#[cfg(feature = "json_serde")] -pub use json_serde::*; -pub use option::*; diff --git a/src/utils/codecs/string/option.rs b/src/utils/codecs/string/option.rs deleted file mode 100644 index 12b1669..0000000 --- a/src/utils/codecs/string/option.rs +++ /dev/null @@ -1,45 +0,0 @@ -use crate::utils::{Decoder, Encoder}; - -/// Wraps a string codec that encodes `T` to create a codec that encodes `Option`. -/// -/// Example: -/// -/// ``` -/// # use leptos_use::utils::{OptionCodec, FromToStringCodec, Encoder, Decoder}; -/// # -/// let original_value = Some(4); -/// let encoded = OptionCodec::::encode(&original_value).unwrap(); -/// let decoded = OptionCodec::::decode(&encoded).unwrap(); -/// -/// assert_eq!(decoded, original_value); -/// ``` -pub struct OptionCodec(C); - -impl Encoder> for OptionCodec -where - E: Encoder, -{ - type Error = E::Error; - type Encoded = String; - - fn encode(val: &Option) -> Result { - match val { - Some(val) => Ok(format!("~<|Some|>~{}", E::encode(val)?)), - None => Ok("~<|None|>~".to_owned()), - } - } -} - -impl Decoder> for OptionCodec -where - D: Decoder, -{ - type Error = D::Error; - type Encoded = str; - - fn decode(str: &Self::Encoded) -> Result, Self::Error> { - str.strip_prefix("~<|Some|>~") - .map(|v| D::decode(v)) - .transpose() - } -} diff --git a/src/utils/mod.rs b/src/utils/mod.rs index d5a1fca..906f4e1 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -1,4 +1,3 @@ -mod codecs; mod filters; mod is; mod js; @@ -7,7 +6,6 @@ mod pausable; mod signal_filtered; mod use_derive_signal; -pub use codecs::*; pub use filters::*; pub use is::*; pub(crate) use js_value_from_to_string::*;