diff --git a/.github/FUNDING.yaml b/.github/FUNDING.yaml new file mode 100644 index 0000000..7a95a98 --- /dev/null +++ b/.github/FUNDING.yaml @@ -0,0 +1,2 @@ +github: EpicEric +liberapay: EpicEric diff --git a/.github/workflows/duper-python.yaml b/.github/workflows/build-duper-python.yaml similarity index 100% rename from .github/workflows/duper-python.yaml rename to .github/workflows/build-duper-python.yaml diff --git a/.github/workflows/validate.yaml b/.github/workflows/validate.yaml new file mode 100644 index 0000000..f0ea93a --- /dev/null +++ b/.github/workflows/validate.yaml @@ -0,0 +1,77 @@ +name: Validate + +on: + push: + branches: ["main"] + pull_request: + branches: ["**"] + +permissions: + contents: read + +env: + RUST_MSRV: "1.88.0" + CARGO_INCREMENTAL: "0" + CARGO_PROFILE_TEST_DEBUG: "0" + PYTHON_MINIMUM_VERSION: "3.10" + +jobs: + rustfmt-msrv: + name: Check rustfmt formatting on MSRV + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + persist-credentials: false + - name: Fetch MSRV + run: | + rustup toolchain install ${RUST_MSRV}-x86_64-unknown-linux-gnu + rustup override set ${RUST_MSRV}-x86_64-unknown-linux-gnu + - name: Run rustfmt + run: | + rustup component add rustfmt + cargo fmt --check --all + build-msrv: + name: Build on MSRV + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + persist-credentials: false + - name: Fetch MSRV + run: | + rustup toolchain install ${RUST_MSRV}-x86_64-unknown-linux-gnu + rustup override set ${RUST_MSRV}-x86_64-unknown-linux-gnu + - name: Cache Rust dependencies + uses: Swatinem/rust-cache@f13886b937689c021905a6b90929199931d60db1 # v2.8.1 + - name: Build + run: | + cargo build --locked --all-features + tests-nightly: + name: Run tests on MSRV + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + persist-credentials: false + - name: Fetch MSRV + run: | + rustup toolchain install ${RUST_MSRV}-x86_64-unknown-linux-gnu + rustup override set ${RUST_MSRV}-x86_64-unknown-linux-gnu + - name: Setup uv + uses: astral-sh/setup-uv@2ddd2b9cb38ad8efd50337e8ab201519a34c9f24 # v7.1.1 + with: + python-version: ${{ env.PYTHON_MINIMUM_VERSION }} + - name: Cache Rust dependencies + uses: Swatinem/rust-cache@f13886b937689c021905a6b90929199931d60db1 # v2.8.1 + - name: Install just + run: | + curl --proto '=https' --tlsv1.2 -sSf https://just.systems/install.sh | bash -s -- --to . + - name: Test + env: + RUSTFLAGS: -A dead_code -A unused_variables + run: | + ./just test diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..4ea201b --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,7 @@ +# Code of Conduct + +This project adheres to the [Rust Code of Conduct](https://www.rust-lang.org/policies/code-of-conduct). This describes the minimum behavior expected from all contributors. + +## Enforcement + +Instances of violations of the Code of Conduct can be reported by contacting the project team at [duper-coc@eric.dev.br](mailto:duper-coc@eric.dev.br). diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..723efb4 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,19 @@ +# Contributing + +Hello, and thank you for taking the time to read the contributing guidelines for Duper! Please read through our [Code of Conduct](./CODE_OF_CONDUCT.md) as well. + +Here are some ways to contribute to the project: + +## Creating issues + +Please search the [existing issues](https://github.com/EpicEric/duper/issues) for any answers or existing discussions before creating your own issue. + +## Submitting changes + +In the case that you'd like to make contributions to Duper, create an issue first if one does not exist. + +If you wish to contribute changes to Duper, please [fork the repository](https://github.com/EpicEric/duper/fork), push your modifications to a branch, and create a [pull request](https://github.com/EpicEric/duper/compare). Make sure to [link to the original issue](https://docs.github.com/en/issues/tracking-your-work-with-issues/using-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword) in your PR's body. + +If possible, make sure that your changes pass all tests and linting/formatting checks before creating a pull request by running `just test` and `just clippy`, respectively. This should ensure that your PR will pass the CI pipeline. + +Please add a short description of any user-facing changes to the top of the [CHANGELOG.md](./CHANGELOG.md) of the appropriate sub-module(s), under the "Unreleased" section (or create one if it does not exist). The changelog should adhere to [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and it must emphasize any breaking changes. diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..a85e369 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,7 @@ +# Security Policy + +## Reporting a Vulnerability + +Please report vunerabilities using Github's Private Vulnerability Reporting tool, or by sending an e-mail to [security-duper@eric.dev.br](mailto:security-duper@eric.dev.br). + +Do not use public Github Issues for reporting vulnerabilities. diff --git a/axum_duper/Cargo.toml b/axum_duper/Cargo.toml index 304f40f..b46ed46 100644 --- a/axum_duper/Cargo.toml +++ b/axum_duper/Cargo.toml @@ -3,6 +3,7 @@ name = "axum_duper" description = "Axum extractor/response for Duper." version = "0.1.2" edition = "2024" +rust-version = "1.88" license = "MIT" authors = ["Eric Rodrigues Pires "] repository = "https://github.com/EpicEric/duper" diff --git a/duper-python/Cargo.toml b/duper-python/Cargo.toml index 289c5fd..569c2a6 100644 --- a/duper-python/Cargo.toml +++ b/duper-python/Cargo.toml @@ -3,6 +3,7 @@ name = "duper-python" description = "The format that's super!" version = "0.1.2" edition = "2024" +rust-version = "1.88" license = "MIT" authors = ["Eric Rodrigues Pires "] repository = "https://github.com/EpicEric/duper" diff --git a/duper-python/pyproject.toml b/duper-python/pyproject.toml index 108833e..cf4843d 100644 --- a/duper-python/pyproject.toml +++ b/duper-python/pyproject.toml @@ -32,6 +32,7 @@ bindings = "pyo3" dev = [ "fastapi[standard]>=0.119.0", "httpx>=0.28.1", + "maturin>=1.9.6", "pytest>=8.4.2", "starlette>=0.48.0", ] diff --git a/duper-python/src/lib.rs b/duper-python/src/lib.rs index 07cc8bd..592ed59 100644 --- a/duper-python/src/lib.rs +++ b/duper-python/src/lib.rs @@ -12,6 +12,7 @@ mod duper_py { use crate::{de::Visitor, ser::serialize_pyany}; + #[allow(clippy::declare_interior_mutable_const)] #[pyfunction] #[pyo3(signature = (obj, *, indent=None, strip_identifiers=false))] fn dumps<'py>( @@ -44,6 +45,7 @@ mod duper_py { } } + #[allow(clippy::declare_interior_mutable_const)] #[pyfunction] #[pyo3(signature = (obj, fp, *, indent=None, strip_identifiers=false))] fn dump<'py>( @@ -81,6 +83,7 @@ mod duper_py { Ok(()) } + #[allow(clippy::declare_interior_mutable_const)] #[pyfunction] #[pyo3(signature = (s, *, parse_any=false))] fn loads<'py>(py: Python<'py>, s: &str, parse_any: bool) -> PyResult> { @@ -97,6 +100,7 @@ mod duper_py { value.accept(&mut Visitor { py }) } + #[allow(clippy::declare_interior_mutable_const)] #[pyfunction] #[pyo3(signature = (fp, *, parse_any=false))] fn load<'py>( diff --git a/duper-python/src/ser.rs b/duper-python/src/ser.rs index 5b19a16..89b77da 100644 --- a/duper-python/src/ser.rs +++ b/duper-python/src/ser.rs @@ -503,8 +503,7 @@ fn serialize_pyclass_identifier<'py>( )?)) .map_err(|error| { PyErr::new::(format!( - "Invalid identifier: {} ({})", - identifier, error + "Invalid identifier: {identifier} ({error})" )) })?, )) @@ -519,8 +518,7 @@ fn serialize_pyclass_identifier<'py>( )?)) .map_err(|error| { PyErr::new::(format!( - "Invalid identifier: {} ({})", - identifier, error + "Invalid identifier: {identifier} ({error})" )) })?, )) diff --git a/duper-python/uv.lock b/duper-python/uv.lock index 887cd17..93c5eed 100644 --- a/duper-python/uv.lock +++ b/duper-python/uv.lock @@ -73,6 +73,7 @@ source = { editable = "." } dev = [ { name = "fastapi", extra = ["standard"] }, { name = "httpx" }, + { name = "maturin" }, { name = "pytest" }, { name = "starlette" }, ] @@ -83,6 +84,7 @@ dev = [ dev = [ { name = "fastapi", extras = ["standard"], specifier = ">=0.119.0" }, { name = "httpx", specifier = ">=0.28.1" }, + { name = "maturin", specifier = ">=1.9.6" }, { name = "pytest", specifier = ">=8.4.2" }, { name = "starlette", specifier = ">=0.48.0" }, ] @@ -381,6 +383,30 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/70/bc/6f1c2f612465f5fa89b95bead1f44dcb607670fd42891d8fdcd5d039f4f4/markupsafe-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa", size = 14146 }, ] +[[package]] +name = "maturin" +version = "1.9.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "tomli", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9a/35/c3370188492f4c139c7a318f438d01b8185c216303c49c4bc885c98b6afb/maturin-1.9.6.tar.gz", hash = "sha256:2c2ae37144811d365509889ed7220b0598487f1278c2441829c3abf56cc6324a", size = 214846 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/55/5c/b435418ba4ba2647a1f7a95d53314991b1e556e656ae276dea993c3bce1d/maturin-1.9.6-py3-none-linux_armv6l.whl", hash = "sha256:26e3ab1a42a7145824210e9d763f6958f2c46afb1245ddd0bab7d78b1f59bb3f", size = 8134483 }, + { url = "https://files.pythonhosted.org/packages/4d/1c/8e58eda6601f328b412cdeeaa88a9b6a10e591e2a73f313e8c0154d68385/maturin-1.9.6-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:5263dda3f71feef2e4122baf5c4620e4b3710dbb7f2121f85a337182de214369", size = 15776470 }, + { url = "https://files.pythonhosted.org/packages/6c/33/8c967cce6848cdd87a2e442c86120ac644b80c5ed4c32e3291bde6a17df8/maturin-1.9.6-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:fe78262c2800c92f67d1ce3c0f6463f958a692cc67bfb572e5dbf5b4b696a8ba", size = 8226557 }, + { url = "https://files.pythonhosted.org/packages/58/bd/3e2675cdc8b7270700ba30c663c852a35694441732a107ac30ebd6878bd8/maturin-1.9.6-py3-none-manylinux_2_12_i686.manylinux2010_i686.musllinux_1_1_i686.whl", hash = "sha256:7ab827c6e8c022eb2e1e7fb6deede54549c8460b20ccc2e9268cc6e8cde957a8", size = 8166544 }, + { url = "https://files.pythonhosted.org/packages/58/1f/a2047ddf2230e700d5f8a13dd4b9af5ce806ad380c32e58105888205926e/maturin-1.9.6-py3-none-manylinux_2_12_x86_64.manylinux2010_x86_64.musllinux_1_1_x86_64.whl", hash = "sha256:0246202377c49449315305209f45c8ecef6e2d6bd27a04b5b6f1ab3e4ea47238", size = 8641010 }, + { url = "https://files.pythonhosted.org/packages/be/1f/265d63c7aa6faf363d4a3f23396f51bc6b4d5c7680a4190ae68dba25dea2/maturin-1.9.6-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:f5bac167700fbb6f8c8ed1a97b494522554b4432d7578e11403b894b6a91d99f", size = 7965945 }, + { url = "https://files.pythonhosted.org/packages/4c/ca/a8e61979ccfe080948bcc1bddd79356157aee687134df7fb013050cec783/maturin-1.9.6-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.musllinux_1_1_armv7l.whl", hash = "sha256:7f53d3b1d8396d3fea3e1ee5fd37558bca5719090f3d194ba1c02b0b56327ae3", size = 7978820 }, + { url = "https://files.pythonhosted.org/packages/bf/4a/81b412f8ad02a99801ef19ec059fba0822d1d28fb44cb6a92e722f05f278/maturin-1.9.6-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.musllinux_1_1_ppc64le.whl", hash = "sha256:7f506eb358386d94d6ec3208c003130cf4b69cab26034fc0cbbf8bf83afa4c2e", size = 10452064 }, + { url = "https://files.pythonhosted.org/packages/5b/12/cc96c7a8cb51d8dcc9badd886c361caa1526fba7fa69d1e7892e613b71d4/maturin-1.9.6-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f2d6984ab690af509f525dbd2b130714207c06ebb14a5814edbe1e42b17ae0de", size = 8852401 }, + { url = "https://files.pythonhosted.org/packages/51/8e/653ac3c9f2c25cdd81aefb0a2d17ff140ca5a14504f5e3c7f94dcfe4dbb7/maturin-1.9.6-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:5c2252b0956bb331460ac750c805ddf0d9b44442449fc1f16e3b66941689d0bc", size = 8425057 }, + { url = "https://files.pythonhosted.org/packages/db/29/f13490328764ae9bfc1da55afc5b707cebe4fa75ad7a1573bfa82cfae0c6/maturin-1.9.6-py3-none-win32.whl", hash = "sha256:f2c58d29ebdd4346fd004e6be213d071fdd94a77a16aa91474a21a4f9dbf6309", size = 7165956 }, + { url = "https://files.pythonhosted.org/packages/db/9f/dd51e5ac1fce47581b8efa03d77a03f928c0ef85b6e48a61dfa37b6b85a2/maturin-1.9.6-py3-none-win_amd64.whl", hash = "sha256:1b39a5d82572c240d20d9e8be024d722dfb311d330c5e28ddeb615211755941a", size = 8145722 }, + { url = "https://files.pythonhosted.org/packages/65/f2/e97aaba6d0d78c5871771bf9dd71d4eb8dac15df9109cf452748d2207412/maturin-1.9.6-py3-none-win_arm64.whl", hash = "sha256:ac02a30083553d2a781c10cd6f5480119bf6692fd177e743267406cad2ad198c", size = 6857006 }, +] + [[package]] name = "mdurl" version = "0.1.2" diff --git a/duper.code-workspace b/duper.code-workspace index 813a324..0746057 100644 --- a/duper.code-workspace +++ b/duper.code-workspace @@ -1,5 +1,9 @@ { "folders": [ + { + "name": "/", + "path": "." + }, { "name": "axum_duper", "path": "axum_duper" @@ -23,10 +27,6 @@ { "name": "serde_duper_macros", "path": "serde_duper_macros" - }, - { - "name": "/", - "path": "." } ], "settings": { diff --git a/duper/Cargo.toml b/duper/Cargo.toml index 939f70f..6781036 100644 --- a/duper/Cargo.toml +++ b/duper/Cargo.toml @@ -3,6 +3,7 @@ name = "duper" description = "The format that's super!" version = "0.1.1" edition = "2024" +rust-version = "1.88" license = "MIT" authors = ["Eric Rodrigues Pires "] repository = "https://github.com/EpicEric/duper" diff --git a/duper/src/format.rs b/duper/src/format.rs index ff2fd97..b92f6d3 100644 --- a/duper/src/format.rs +++ b/duper/src/format.rs @@ -69,7 +69,7 @@ fn format_cow_str<'a>(string: &Cow<'a, str>) -> Cow<'a, str> { if chars_to_escape > max_hashtags && !has_char_that_should_be_escaped { // Raw string let hashtags: String = (0..max_hashtags).map(|_| '#').collect(); - Cow::Owned(format!(r#"r{}"{}"{}"#, hashtags, string, hashtags)) + Cow::Owned(format!(r#"r{hashtags}"{string}"{hashtags}"#)) } else { // Regular string with escaping let escaped_key = escape_str(string); @@ -130,10 +130,7 @@ pub(crate) fn format_duper_bytes<'a>(bytes: &'a DuperBytes<'a>) -> Cow<'a, str> // Raw bytes let hashtags: String = (0..max_hashtags).map(|_| '#').collect(); let unesecaped_bytes: String = bytes.0.iter().copied().map(|b| b as char).collect(); - Cow::Owned(format!( - r#"br{}"{}"{}"#, - hashtags, unesecaped_bytes, hashtags - )) + Cow::Owned(format!(r#"br{hashtags}"{unesecaped_bytes}"{hashtags}"#)) } else { // Regular bytes with escaping let escaped_bytes = escape_bytes(&bytes.0); diff --git a/duper/src/visitor/ansi.rs b/duper/src/visitor/ansi.rs index 367ef01..6cf9a08 100644 --- a/duper/src/visitor/ansi.rs +++ b/duper/src/visitor/ansi.rs @@ -128,7 +128,7 @@ impl<'ansi> Ansi<'ansi> { fn colorize_bracket(&mut self, bracket: &str) -> Result<(), Error> { if self.theme.brackets.is_empty() { - self.buf.write(bracket.as_bytes())?; + self.buf.write_all(bracket.as_bytes())?; Ok(()) } else { self.buf.write_fmt(format_args!( @@ -163,10 +163,10 @@ impl<'ansi> DuperVisitor for Ansi<'ansi> { for (i, (key, value)) in object.iter().enumerate() { self.buf .write_fmt(format_args!("{}", format_key(key).color(self.theme.key)))?; - self.buf.write(b": ")?; + self.buf.write_all(b": ")?; value.accept(self)?; if i < len - 1 { - self.buf.write(b", ")?; + self.buf.write_all(b", ")?; } } self.decrease_bracket_depth(); @@ -179,10 +179,10 @@ impl<'ansi> DuperVisitor for Ansi<'ansi> { for (i, (key, value)) in object.iter().enumerate() { self.buf .write_fmt(format_args!("{}", format_key(key).color(self.theme.key)))?; - self.buf.write(b": ")?; + self.buf.write_all(b": ")?; value.accept(self)?; if i < len - 1 { - self.buf.write(b", ")?; + self.buf.write_all(b", ")?; } } self.decrease_bracket_depth(); @@ -213,7 +213,7 @@ impl<'ansi> DuperVisitor for Ansi<'ansi> { for (i, value) in array.iter().enumerate() { value.accept(self)?; if i < len - 1 { - self.buf.write(b", ")?; + self.buf.write_all(b", ")?; } } self.decrease_bracket_depth(); @@ -226,7 +226,7 @@ impl<'ansi> DuperVisitor for Ansi<'ansi> { for (i, value) in array.iter().enumerate() { value.accept(self)?; if i < len - 1 { - self.buf.write(b", ")?; + self.buf.write_all(b", ")?; } } self.decrease_bracket_depth(); @@ -257,7 +257,7 @@ impl<'ansi> DuperVisitor for Ansi<'ansi> { for (i, value) in tuple.iter().enumerate() { value.accept(self)?; if i < len - 1 { - self.buf.write(b", ")?; + self.buf.write_all(b", ")?; } } self.decrease_bracket_depth(); @@ -270,7 +270,7 @@ impl<'ansi> DuperVisitor for Ansi<'ansi> { for (i, value) in tuple.iter().enumerate() { value.accept(self)?; if i < len - 1 { - self.buf.write(b", ")?; + self.buf.write_all(b", ")?; } } self.decrease_bracket_depth(); diff --git a/justfile b/justfile new file mode 100644 index 0000000..87e54fc --- /dev/null +++ b/justfile @@ -0,0 +1,15 @@ +default: + just --list + +test: test-rust test-python + +test-rust: + cargo test --all-features + +[working-directory: 'duper-python'] +test-python: + uv run maturin develop + uv run pytest -vv + +clippy: + cargo clippy --all-features --all-targets --fix --allow-dirty --allow-staged && cargo fmt --all diff --git a/serde_duper/Cargo.toml b/serde_duper/Cargo.toml index 75d1497..eb0cde2 100644 --- a/serde_duper/Cargo.toml +++ b/serde_duper/Cargo.toml @@ -3,6 +3,7 @@ name = "serde_duper" description = "Serde support for Duper." version = "0.1.2" edition = "2024" +rust-version = "1.88" license = "MIT" authors = ["Eric Rodrigues Pires "] repository = "https://github.com/EpicEric/duper" diff --git a/serde_duper/src/de.rs b/serde_duper/src/de.rs index 616fe27..f2c25b3 100644 --- a/serde_duper/src/de.rs +++ b/serde_duper/src/de.rs @@ -42,17 +42,17 @@ impl<'de> Deserializer<'de> { /// location: String, /// } /// -/// fn main() { -/// // The type of `j` is `&str` -/// let j = r#" -/// User({ -/// fingerprint: b"\xF9\xBA\x14\x3B\x95\xFF\x6D\x82", -/// location: City("Menlo Park, CA"), -/// })"#; /// -/// let u: User = serde_duper::from_string(j).unwrap(); -/// println!("{:#?}", u); -/// } +/// // The type of `j` is `&str` +/// let j = r#" +/// User({ +/// fingerprint: b"\xF9\xBA\x14\x3B\x95\xFF\x6D\x82", +/// location: City("Menlo Park, CA"), +/// })"#; +/// +/// let u: User = serde_duper::from_string(j).unwrap(); +/// println!("{:#?}", u); +/// /// ``` /// /// # Errors @@ -91,37 +91,35 @@ where /// location: String, /// } /// -/// fn main() { -/// // The type of `d` is `serde_duper::DuperValue` -/// let d = DuperValue { -/// identifier: Some(DuperIdentifier::try_from(Cow::Borrowed("User")).unwrap()), -/// inner: DuperInner::Object(DuperObject::try_from(vec![ -/// ( -/// DuperKey::from(Cow::Borrowed("fingerprint")), -/// DuperValue { -/// identifier: None, -/// inner: DuperInner::Bytes(DuperBytes::from(Cow::Borrowed( -/// &b"\xF9\xBA\x14\x3B\x95\xFF\x6D\x82"[..], -/// ))), -/// } -/// ), -/// ( -/// DuperKey::from(Cow::Borrowed("location")), -/// DuperValue { -/// identifier: Some( -/// DuperIdentifier::try_from(Cow::Borrowed("City")).unwrap(), -/// ), -/// inner: DuperInner::String(DuperString::from( -/// Cow::Borrowed("Menlo Park, CA"), -/// )), -/// } -/// ), -/// ]).unwrap()), -/// }; +/// // The type of `d` is `serde_duper::DuperValue` +/// let d = DuperValue { +/// identifier: Some(DuperIdentifier::try_from(Cow::Borrowed("User")).unwrap()), +/// inner: DuperInner::Object(DuperObject::try_from(vec![ +/// ( +/// DuperKey::from(Cow::Borrowed("fingerprint")), +/// DuperValue { +/// identifier: None, +/// inner: DuperInner::Bytes(DuperBytes::from(Cow::Borrowed( +/// &b"\xF9\xBA\x14\x3B\x95\xFF\x6D\x82"[..], +/// ))), +/// } +/// ), +/// ( +/// DuperKey::from(Cow::Borrowed("location")), +/// DuperValue { +/// identifier: Some( +/// DuperIdentifier::try_from(Cow::Borrowed("City")).unwrap(), +/// ), +/// inner: DuperInner::String(DuperString::from( +/// Cow::Borrowed("Menlo Park, CA"), +/// )), +/// } +/// ), +/// ]).unwrap()), +/// }; /// -/// let u: User = serde_duper::from_value(d).unwrap(); -/// println!("{:#?}", u); -/// } +/// let u: User = serde_duper::from_value(d).unwrap(); +/// println!("{:#?}", u); /// ``` /// /// # Errors diff --git a/serde_duper/src/ser.rs b/serde_duper/src/ser.rs index eaaf8c8..be61d40 100644 --- a/serde_duper/src/ser.rs +++ b/serde_duper/src/ser.rs @@ -9,7 +9,7 @@ use serde_core::{Serialize, ser}; use crate::Error; /// A structure for serializing Rust values into Duper values. -#[derive(Clone)] +#[derive(Clone, Default)] pub struct Serializer<'a> { _marker: PhantomData>, } @@ -17,9 +17,7 @@ pub struct Serializer<'a> { impl<'a> Serializer<'a> { /// Creates a new Duper serializer. pub fn new() -> Self { - Self { - _marker: Default::default(), - } + Self::default() } } diff --git a/serde_duper/tests/types_option_some.rs b/serde_duper/tests/types_option_some.rs index 463b61e..57a5bf0 100644 --- a/serde_duper/tests/types_option_some.rs +++ b/serde_duper/tests/types_option_some.rs @@ -444,9 +444,11 @@ fn some_ffi_unix() { os_str: Option<&'a OsStr>, } + let c_string = CString::new("goodbye").unwrap(); + let os_string = OsString::from("test_os_str"); let value = TestSerializeOnly { - c_str: Some(&CString::new("goodbye").unwrap()), - os_str: Some(&OsString::from("test_os_str")), + c_str: Some(&c_string), + os_str: Some(&os_string), }; let serialized = serde_duper::to_string(&value).unwrap(); diff --git a/serde_duper_macros/Cargo.toml b/serde_duper_macros/Cargo.toml index 1ce8f0f..b23b92f 100644 --- a/serde_duper_macros/Cargo.toml +++ b/serde_duper_macros/Cargo.toml @@ -3,6 +3,7 @@ name = "serde_duper_macros" description = "Macros for serde_duper." version = "0.1.0" edition = "2024" +rust-version = "1.88" license = "MIT" authors = ["Eric Rodrigues Pires "] repository = "https://github.com/EpicEric/duper" diff --git a/serde_duper_macros/src/lib.rs b/serde_duper_macros/src/lib.rs index c402d9b..f695e30 100644 --- a/serde_duper_macros/src/lib.rs +++ b/serde_duper_macros/src/lib.rs @@ -121,7 +121,7 @@ fn process_field( } }; - let path_string = format!("{}", mod_ident); + let path_string = format!("{mod_ident}"); let serde_with_attr: Attribute = syn::parse_quote! { #[serde(with = #path_string)]