diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..860f849 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,109 @@ +name: Simple build & test + +on: + push: + branches: [ "master" ] + pull_request: + branches: [ "master" ] + +env: + CARGO_TERM_COLOR: always + +jobs: + tests: + name: ${{ matrix.make.name }} (${{ matrix.os }}) + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, macos-latest] + rust: [stable, nightly] + task: + - name: Clippy + cmd: "cargo clippy -D warnings" + - name: Test + cmd: "cargo test" + - name: Format + cmd: "cargo fmt --all --check" + - name: Build + cmd: "cargo build --frozen --release" + include: + - os: ubuntu-latest + sccache-path: /home/runner/.cache/sccache + - os: macos-latest + sccache-path: /Users/runner/Library/Caches/Mozilla.sccache + exclude: + - os: macos-latest + rust: stable + task: + name: Clippy + - os: macos-latest + rust: nightly + task: + name: Clippy + - os: macos-latest + rust: stable + task: + name: Format + - os: macos-latest + rust: nightly + task: + name: Format + env: + RUST_BACKTRACE: full + RUSTC_WRAPPER: sccache + RUSTV: ${{ matrix.rust }} + SCCACHE_CACHE_SIZE: 2G + SCCACHE_DIR: ${{ matrix.sccache-path }} + steps: + - uses: actions/checkout@v3 + - name: Install sccache (ubuntu-latest) + if: matrix.os == 'ubuntu-latest' + env: + LINK: https://github.com/mozilla/sccache/releases/download + SCCACHE_VERSION: 0.2.13 + run: | + SCCACHE_FILE=sccache-$SCCACHE_VERSION-x86_64-unknown-linux-musl + mkdir -p $HOME/.local/bin + curl -L "$LINK/$SCCACHE_VERSION/$SCCACHE_FILE.tar.gz" | tar xz + mv -f $SCCACHE_FILE/sccache $HOME/.local/bin/sccache + echo "$HOME/.local/bin" >> $GITHUB_PATH + - name: Install sccache (macos-latest) + if: matrix.os == 'macos-latest' + run: | + brew update + brew install sccache + - name: Install Rust ${{ matrix.rust }} + uses: actions-rs/toolchain@v1 + with: + toolchain: ${{ matrix.rust }} + profile: minimal + override: true + - name: Cache cargo registry + uses: actions/cache@v2 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} + restore-keys: | + ${{ runner.os }}-cargo- + - name: Save sccache + uses: actions/cache@v2 + with: + path: ${{ matrix.sccache-path }} + key: ${{ runner.os }}-sccache-${{ hashFiles('**/Cargo.lock') }} + restore-keys: | + ${{ runner.os }}-sccache- + - name: Start sccache server + run: sccache --start-server + - name: Install rustfmt + if: matrix.task.name == 'Format' + run: rustup component add rustfmt + - name: ${{ matrix.task.name }} + run: ${{ matrix.task.cmd }} + - name: Print sccache stats + run: sccache --show-stats + - name: Stop sccache server + run: sccache --stop-server + continue-on-error: true diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc new file mode 100644 index 0000000..364a378 --- /dev/null +++ b/CHANGELOG.adoc @@ -0,0 +1,65 @@ += Changelog +:toc: +:toclevels: 1 +:idprefix: +:idseparator: - + +== [Unreleased] + +== [v1.1.0] - 2024-03-21 + +=== Added + +- implement serializing into generic `io::Write` + +=== Fixed + +- fix parsing CRLF + +== [v1.0.0] - 2023-03-10 + +=== Added + +- implement literal strings + +=== Fixed + +- fix serializing strings containing `:` +- fix serializing certain escaped characters + +== [v0.2.4] - 2023-03-01 + +=== Fixed + +- fix incorrect parsing of unquoted strings + +== [v0.2.3] - 2023-02-24 + +=== Fixed + +- support backslashes in delimited strings + +== [v0.2.2] - 2023-02-18 + +=== Fixed + +- fix deserialization failing on arrays and objects in some cases + +== [v0.2.1] - 2022-12-28 + +=== Fixed + +- fix serializing Unicode + +== [v0.2.0] - 2022-11-25 + +=== Added + +* parsing & deserialization + +== [v0.1.0] - 2022-11-18 + +=== Added + +* initial release +* serialization diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index c76f9fa..0000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,75 +0,0 @@ -# Changelog - - - -## [Unreleased] - ReleaseDate - -## [1.2.1] - 2025-04-21 - -### Changed - -- update [nom](https://crates.io/crates/nom) to v8 - -## [1.2.0] - 2024-03-21 - -### Added - -- publishing to [crates.io](https://crates.io) - -## [v1.1.0] - 2024-03-21 - -### Added - -- implement serializing into generic `io::Write` - -### Fixed - -- fix parsing CRLF - -## [v1.0.0] - 2023-03-10 - -### Added - -- implement literal strings - -### Fixed - -- fix serializing strings containing `:` -- fix serializing certain escaped characters - -## [v0.2.4] - 2023-03-01 - -### Fixed - -- fix incorrect parsing of unquoted strings - -## [v0.2.3] - 2023-02-24 - -### Fixed - -- support backslashes in delimited strings - -## [v0.2.2] - 2023-02-18 - -### Fixed - -- fix deserialization failing on arrays and objects in some cases - -## [v0.2.1] - 2022-12-28 - -### Fixed - -- fix serializing Unicode - -## [v0.2.0] - 2022-11-25 - -### Added - -* parsing & deserialization - -## [v0.1.0] - 2022-11-18 - -### Added - -* initial release -* serialization diff --git a/Cargo.toml b/Cargo.toml index 9b49a39..3526b48 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,27 +1,15 @@ [package] name = "serde_sjson" -version = "1.2.1" -authors = ["Lucas Schwiderski"] -categories = ["encoding", "parser-implementations"] -description = "An SJSON serialization file format" -documentation = "https://docs.rs/serde_sjson" +version = "1.1.0" edition = "2021" keywords = ["serde", "serialization", "sjson"] -license-file = "LICENSE" -repository = "https://github.com/sclu1034/serde_sjson" -exclude = [ - ".github/", - ".ci/", - "Justfile" -] +description = "An SJSON serialization file format" +categories = ["encoding", "parser-implementations"] [dependencies] -nom = "8" -nom_locate = "5" -serde = { version = "1.0", default-features = false } +nom = "7.1.3" +nom_locate = "4.1.0" +serde = { version = "1.0.154", default-features = false } [dev-dependencies] -serde = { version = "1.0", features = ["derive"] } - -[badges] -maintenance = { status = "passively-maintained" } +serde = { version = "1.0.154", features = ["derive"] } diff --git a/Justfile b/Justfile index 51ceb16..c052f9a 100644 --- a/Justfile +++ b/Justfile @@ -1,33 +1,12 @@ project := "serde_sjson" default := "run" -build *ARGS: - cargo build {{ARGS}} - cargo readme > README.md - run *ARGS: cargo run -- {{ARGS}} test *ARGS: cargo test {{ARGS}} -check: - cargo clippy -- -D warnings - cargo test - -doc: - cargo doc --no-deps - cargo readme > README.md - -serve-doc port='8000': doc - python3 -m http.server {{port}} --directory target/doc - -release version execute='': check build doc - git fetch --all - [ "$(git rev-parse master)" = "$(git rev-parse origin/master)" ] \ - || (echo "error: master and origin/master differ" >&2; exit 1) - cargo release --sign --allow-branch master {{ if execute != "" { '-x' } else { '' } }} {{version}} - coverage *ARGS: RUSTFLAGS="-C instrument-coverage" cargo test --tests {{ARGS}} || true cargo profdata -- merge -sparse default*.profraw -o {{project}}.profdata diff --git a/README.adoc b/README.adoc new file mode 100644 index 0000000..56a9faf --- /dev/null +++ b/README.adoc @@ -0,0 +1,13 @@ += Serde SJSON +:idprefix: +:idseparator: +:toc: macro +:toclevels: 1 +:!toc-title: +:caution-caption: :fire: +:important-caption: :exclamtion: +:note-caption: :paperclip: +:tip-caption: :bulb: +:warning-caption: :warning: + +A __ser__ialization/__de__serialization library for __Simplified JSON__, specifically, the Bitsquid/Stingray flavor. diff --git a/README.md b/README.md deleted file mode 100644 index 7b60d9e..0000000 --- a/README.md +++ /dev/null @@ -1,69 +0,0 @@ -# serde_sjson - -A **ser**ialization/**de**serialization library for Simplified JSON, -the Bitsquid/Stingray flavor of JSON. - -## Usage - -### Serializing - -```rust -use serde::Serialize; -use serde_sjson::Result; - -#[derive(Serialize)] -struct Person { - name: String, - age: u8, - friends: Vec, -} - -fn main() -> Result<()> { - let data = Person { - name: String::from("Marc"), - age: 21, - friends: vec![String::from("Jessica"), String::from("Paul")], - }; - - let s = serde_sjson::to_string(&data)?; - - println!("{}", s); - - Ok(()) -} -``` - -### Deserializing - -```rust -use serde::Deserialize; -use serde_sjson::Result; - -#[derive(Deserialize)] -struct Person { - name: String, - age: u8, - friends: Vec, -} - -fn main() -> Result<()> { - let sjson = r#" - name = Marc - age = 21 - friends = [ - Jessica - Paul - ]"#; - - let data: Person = serde_sjson::from_str(sjson)?; - - println!( - "{} is {} years old and has {} friends.", - data.name, - data.age, - data.friends.len() - ); - - Ok(()) -} -``` diff --git a/README.tpl b/README.tpl deleted file mode 100644 index 0d9b104..0000000 --- a/README.tpl +++ /dev/null @@ -1,3 +0,0 @@ -# {{crate}} - -{{readme}} diff --git a/release.toml b/release.toml deleted file mode 100644 index df0c8c9..0000000 --- a/release.toml +++ /dev/null @@ -1,5 +0,0 @@ -pre-release-replacements = [ - {file="CHANGELOG.md", search="Unreleased", replace="{{version}}"}, - {file="CHANGELOG.md", search="ReleaseDate", replace="{{date}}"}, - {file="CHANGELOG.md", search="", replace="\n\n## [Unreleased] - ReleaseDate", exactly=1}, -] diff --git a/src/de.rs b/src/de.rs index afbb9b3..8d35613 100644 --- a/src/de.rs +++ b/src/de.rs @@ -5,7 +5,6 @@ use serde::Deserialize; use crate::error::{Error, ErrorCode, Result}; use crate::parser::*; -/// A container for deserializing Rust values from SJSON. pub struct Deserializer<'de> { input: Span<'de>, is_top_level: bool, @@ -13,7 +12,7 @@ pub struct Deserializer<'de> { impl<'de> Deserializer<'de> { #![allow(clippy::should_implement_trait)] - pub(crate) fn from_str(input: &'de str) -> Self { + pub fn from_str(input: &'de str) -> Self { Self { input: Span::from(input), is_top_level: true, @@ -66,8 +65,6 @@ impl<'de> Deserializer<'de> { } } -/// Deserializes an SJSON string to a Rust value. -#[inline] pub fn from_str<'a, T>(input: &'a str) -> Result where T: Deserialize<'a>, @@ -81,7 +78,7 @@ where } } -impl<'de> serde::de::Deserializer<'de> for &mut Deserializer<'de> { +impl<'de, 'a> serde::de::Deserializer<'de> for &'a mut Deserializer<'de> { type Error = Error; fn deserialize_any(self, visitor: V) -> Result @@ -421,7 +418,7 @@ impl<'a, 'de: 'a> Separated<'a, 'de> { } } -impl<'de> serde::de::SeqAccess<'de> for Separated<'_, 'de> { +impl<'de, 'a> serde::de::SeqAccess<'de> for Separated<'a, 'de> { type Error = Error; fn next_element_seed(&mut self, seed: T) -> Result> @@ -443,7 +440,7 @@ impl<'de> serde::de::SeqAccess<'de> for Separated<'_, 'de> { } } -impl<'de> serde::de::MapAccess<'de> for Separated<'_, 'de> { +impl<'de, 'a> serde::de::MapAccess<'de> for Separated<'a, 'de> { type Error = Error; fn next_key_seed(&mut self, seed: K) -> Result> @@ -487,7 +484,7 @@ impl<'a, 'de> Enum<'a, 'de> { } } -impl<'de> EnumAccess<'de> for Enum<'_, 'de> { +impl<'de, 'a> EnumAccess<'de> for Enum<'a, 'de> { type Error = Error; type Variant = Self; @@ -505,7 +502,7 @@ impl<'de> EnumAccess<'de> for Enum<'_, 'de> { } } -impl<'de> VariantAccess<'de> for Enum<'_, 'de> { +impl<'de, 'a> VariantAccess<'de> for Enum<'a, 'de> { type Error = Error; fn unit_variant(self) -> Result<()> { diff --git a/src/error.rs b/src/error.rs index 9673524..feee003 100644 --- a/src/error.rs +++ b/src/error.rs @@ -2,11 +2,8 @@ use std::{fmt, io}; use crate::parser::Token; -/// An alias for a `Result` with `serde_sjson::Error`. pub type Result = std::result::Result; -/// A type encapsulating the different errors that might occurr -/// during serialization or deserialization. #[derive(PartialEq)] pub struct Error { inner: Box, diff --git a/src/lib.rs b/src/lib.rs index afac0e7..ea30715 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,71 +1,3 @@ -//! A **ser**ialization/**de**serialization library for Simplified JSON, -//! the Bitsquid/Stingray flavor of JSON. -//! -//! # Usage -//! -//! ## Serializing -//! -//! ``` -//! use serde::Serialize; -//! use serde_sjson::Result; -//! -//! #[derive(Serialize)] -//! struct Person { -//! name: String, -//! age: u8, -//! friends: Vec, -//! } -//! -//! fn main() -> Result<()> { -//! let data = Person { -//! name: String::from("Marc"), -//! age: 21, -//! friends: vec![String::from("Jessica"), String::from("Paul")], -//! }; -//! -//! let s = serde_sjson::to_string(&data)?; -//! -//! println!("{}", s); -//! -//! Ok(()) -//! } -//! ``` -//! -//! ## Deserializing -//! -//! ``` -//! use serde::Deserialize; -//! use serde_sjson::Result; -//! -//! #[derive(Deserialize)] -//! struct Person { -//! name: String, -//! age: u8, -//! friends: Vec, -//! } -//! -//! fn main() -> Result<()> { -//! let sjson = r#" -//! name = Marc -//! age = 21 -//! friends = [ -//! Jessica -//! Paul -//! ]"#; -//! -//! let data: Person = serde_sjson::from_str(sjson)?; -//! -//! println!( -//! "{} is {} years old and has {} friends.", -//! data.name, -//! data.age, -//! data.friends.len() -//! ); -//! -//! Ok(()) -//! } -//! ``` - mod de; mod error; mod parser; diff --git a/src/parser.rs b/src/parser.rs index b471e31..573d1ce 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -4,8 +4,8 @@ use nom::character::complete::{char, digit1, none_of, not_line_ending, one_of}; use nom::combinator::{cut, eof, map, map_res, opt, recognize, value}; use nom::multi::many1_count; use nom::number::complete::double; -use nom::sequence::{delimited, preceded, terminated}; -use nom::{IResult, Input as _, Parser as _}; +use nom::sequence::{delimited, preceded, terminated, tuple}; +use nom::{IResult, Slice}; use nom_locate::LocatedSpan; pub(crate) type Span<'a> = LocatedSpan<&'a str>; @@ -35,25 +35,23 @@ fn whitespace(input: Span) -> IResult { } fn null(input: Span) -> IResult { - value((), tag("null")).parse(input) + value((), tag("null"))(input) } fn separator(input: Span) -> IResult { map(alt((tag(","), tag("\n"), tag("\r\n"))), |val: Span| { *val.fragment() - }) - .parse(input) + })(input) } fn bool(input: Span) -> IResult { - alt((value(true, tag("true")), value(false, tag("false")))).parse(input) + alt((value(true, tag("true")), value(false, tag("false"))))(input) } fn integer(input: Span) -> IResult { - map_res(recognize((opt(char('-')), digit1)), |val: Span| { + map_res(recognize(tuple((opt(char('-')), digit1))), |val: Span| { val.fragment().parse::() - }) - .parse(input) + })(input) } fn float(input: Span) -> IResult { @@ -63,16 +61,14 @@ fn float(input: Span) -> IResult { fn identifier(input: Span) -> IResult { map(recognize(many1_count(none_of("\" \t\n=:"))), |val: Span| { *val.fragment() - }) - .parse(input) + })(input) } fn literal_string(input: Span) -> IResult { map( delimited(tag("\"\"\""), take_until("\"\"\""), tag("\"\"\"")), |val: Span| *val.fragment(), - ) - .parse(input) + )(input) } fn string_content(input: Span) -> IResult { @@ -88,51 +84,49 @@ fn string_content(input: Span) -> IResult { } '\n' if !escaped => { let err = nom::error::Error { - input: input.take_from(j), + input: input.slice(j..), code: nom::error::ErrorKind::Char, }; return Err(nom::Err::Error(err)); } '"' if !escaped => { - return Ok((input.take_from(j), &buf[0..j])); + return Ok((input.slice(j..), &buf[0..j])); } _ => escaped = false, } } let err = nom::error::Error { - input: input.take_from(i + 1), + input: input.slice((i + 1)..), code: nom::error::ErrorKind::Char, }; Err(nom::Err::Failure(err)) } fn delimited_string(input: Span) -> IResult { - preceded(char('"'), cut(terminated(string_content, char('"')))).parse(input) + preceded(char('"'), cut(terminated(string_content, char('"'))))(input) } fn string(input: Span) -> IResult { - alt((identifier, literal_string, delimited_string)).parse(input) + alt((identifier, literal_string, delimited_string))(input) } fn line_comment(input: Span) -> IResult { map( preceded(tag("//"), alt((not_line_ending, eof))), |val: Span| *val.fragment(), - ) - .parse(input) + )(input) } fn block_comment(input: Span) -> IResult { map( delimited(tag("/*"), take_until("*/"), tag("*/")), |val: Span| *val.fragment(), - ) - .parse(input) + )(input) } fn comment(input: Span) -> IResult { - alt((line_comment, block_comment)).parse(input) + alt((line_comment, block_comment))(input) } fn optional(input: Span) -> IResult { @@ -141,7 +135,7 @@ fn optional(input: Span) -> IResult { let empty = value((), tag("")); let content = value((), many1_count(alt((whitespace, comment)))); - alt((content, empty)).parse(input) + alt((content, empty))(input) } pub(crate) fn parse_next_token(input: Span) -> IResult { @@ -165,48 +159,45 @@ pub(crate) fn parse_next_token(input: Span) -> IResult { map(float, Token::Float), map(string, |val| Token::String(val.to_string())), )), - ) - .parse(input) + )(input) } pub(crate) fn parse_trailing_characters(input: Span) -> IResult { - value((), optional).parse(input) + value((), optional)(input) } pub(crate) fn parse_null(input: Span) -> IResult { - preceded(optional, value(Token::Null, null)).parse(input) + preceded(optional, value(Token::Null, null))(input) } pub(crate) fn parse_separator(input: Span) -> IResult { preceded( opt(horizontal_whitespace), value(Token::Separator, separator), - ) - .parse(input) + )(input) } pub(crate) fn parse_bool(input: Span) -> IResult { - preceded(optional, map(bool, Token::Boolean)).parse(input) + preceded(optional, map(bool, Token::Boolean))(input) } pub(crate) fn parse_integer(input: Span) -> IResult { - preceded(optional, map(integer, Token::Integer)).parse(input) + preceded(optional, map(integer, Token::Integer))(input) } pub(crate) fn parse_float(input: Span) -> IResult { - preceded(optional, map(float, Token::Float)).parse(input) + preceded(optional, map(float, Token::Float))(input) } pub(crate) fn parse_identifier(input: Span) -> IResult { preceded( optional, map(identifier, |val| Token::String(val.to_string())), - ) - .parse(input) + )(input) } pub(crate) fn parse_string(input: Span) -> IResult { - preceded(optional, map(string, |val| Token::String(val.to_string()))).parse(input) + preceded(optional, map(string, |val| Token::String(val.to_string())))(input) } #[cfg(test)] diff --git a/src/ser.rs b/src/ser.rs index b77799d..532f78f 100644 --- a/src/ser.rs +++ b/src/ser.rs @@ -7,14 +7,12 @@ use crate::error::{Error, ErrorCode, Result}; // TODO: Make configurable const INDENT: [u8; 2] = [0x20, 0x20]; -/// A container for serializing Rust values into SJSON. pub struct Serializer { // The current indentation level level: usize, writer: W, } -/// Serializes a value into a generic `io::Write`. #[inline] pub fn to_writer(writer: &mut W, value: &T) -> Result<()> where @@ -25,7 +23,6 @@ where value.serialize(&mut serializer) } -/// Serializes a value into a byte vector. #[inline] pub fn to_vec(value: &T) -> Result> where @@ -36,7 +33,6 @@ where Ok(vec) } -/// Serializes a value into a string. #[inline] pub fn to_string(value: &T) -> Result where @@ -55,7 +51,6 @@ impl Serializer where W: io::Write, { - /// Creates a new `Serializer`. pub fn new(writer: W) -> Self { Self { level: 0, writer } } @@ -84,7 +79,7 @@ where } } -impl serde::ser::Serializer for &mut Serializer +impl<'a, W> serde::ser::Serializer for &'a mut Serializer where W: io::Write, { @@ -216,9 +211,9 @@ where self.serialize_unit() } - fn serialize_some(self, value: &T) -> Result + fn serialize_some(self, value: &T) -> Result where - T: serde::Serialize + ?Sized, + T: serde::Serialize, { self.ensure_top_level_struct()?; @@ -245,9 +240,9 @@ where self.serialize_str(variant) } - fn serialize_newtype_struct(self, _name: &'static str, value: &T) -> Result + fn serialize_newtype_struct(self, _name: &'static str, value: &T) -> Result where - T: serde::Serialize + ?Sized, + T: serde::Serialize, { self.ensure_top_level_struct()?; @@ -255,7 +250,7 @@ where } // Serialize an externally tagged enum: `{ NAME = VALUE }`. - fn serialize_newtype_variant( + fn serialize_newtype_variant( self, _name: &'static str, _variant_index: u32, @@ -263,7 +258,7 @@ where value: &T, ) -> Result where - T: serde::Serialize + ?Sized, + T: serde::Serialize, { self.ensure_top_level_struct()?; @@ -345,24 +340,24 @@ where Ok(self) } - fn collect_str(self, value: &T) -> Result + fn collect_str(self, value: &T) -> Result where - T: std::fmt::Display + ?Sized, + T: std::fmt::Display, { self.serialize_str(&value.to_string()) } } -impl serde::ser::SerializeSeq for &mut Serializer +impl<'a, W> serde::ser::SerializeSeq for &'a mut Serializer where W: io::Write, { type Ok = (); type Error = Error; - fn serialize_element(&mut self, value: &T) -> Result<()> + fn serialize_element(&mut self, value: &T) -> Result<()> where - T: Serialize + ?Sized, + T: Serialize, { self.add_indent()?; value.serialize(&mut **self)?; @@ -376,16 +371,16 @@ where } } -impl serde::ser::SerializeTuple for &mut Serializer +impl<'a, W> serde::ser::SerializeTuple for &'a mut Serializer where W: io::Write, { type Ok = (); type Error = Error; - fn serialize_element(&mut self, value: &T) -> Result<()> + fn serialize_element(&mut self, value: &T) -> Result<()> where - T: Serialize + ?Sized, + T: Serialize, { self.add_indent()?; value.serialize(&mut **self)?; @@ -399,16 +394,16 @@ where } } -impl serde::ser::SerializeTupleStruct for &mut Serializer +impl<'a, W> serde::ser::SerializeTupleStruct for &'a mut Serializer where W: io::Write, { type Ok = (); type Error = Error; - fn serialize_field(&mut self, value: &T) -> Result<()> + fn serialize_field(&mut self, value: &T) -> Result<()> where - T: Serialize + ?Sized, + T: Serialize, { self.add_indent()?; value.serialize(&mut **self)?; @@ -422,16 +417,16 @@ where } } -impl serde::ser::SerializeTupleVariant for &mut Serializer +impl<'a, W> serde::ser::SerializeTupleVariant for &'a mut Serializer where W: io::Write, { type Ok = (); type Error = Error; - fn serialize_field(&mut self, value: &T) -> Result<()> + fn serialize_field(&mut self, value: &T) -> Result<()> where - T: Serialize + ?Sized, + T: Serialize, { self.add_indent()?; value.serialize(&mut **self)?; @@ -454,24 +449,24 @@ where } } -impl serde::ser::SerializeMap for &mut Serializer +impl<'a, W> serde::ser::SerializeMap for &'a mut Serializer where W: io::Write, { type Ok = (); type Error = Error; - fn serialize_key(&mut self, key: &T) -> Result<()> + fn serialize_key(&mut self, key: &T) -> Result<()> where - T: Serialize + ?Sized, + T: Serialize, { self.add_indent()?; key.serialize(&mut **self) } - fn serialize_value(&mut self, value: &T) -> Result<()> + fn serialize_value(&mut self, value: &T) -> Result<()> where - T: Serialize + ?Sized, + T: Serialize, { // It doesn't make a difference where the `=` is added. But doing it here // means `serialize_key` is only a call to a different function, which should @@ -491,16 +486,16 @@ where } } -impl serde::ser::SerializeStruct for &mut Serializer +impl<'a, W> serde::ser::SerializeStruct for &'a mut Serializer where W: io::Write, { type Ok = (); type Error = Error; - fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<()> + fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<()> where - T: Serialize + ?Sized, + T: Serialize, { self.add_indent()?; key.serialize(&mut **self)?; @@ -521,16 +516,16 @@ where } } -impl serde::ser::SerializeStructVariant for &mut Serializer +impl<'a, W> serde::ser::SerializeStructVariant for &'a mut Serializer where W: std::io::Write, { type Ok = (); type Error = Error; - fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<()> + fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<()> where - T: Serialize + ?Sized, + T: Serialize, { self.add_indent()?; key.serialize(&mut **self)?; diff --git a/tests/serialize.rs b/tests/serialize.rs index 380fec0..7afb926 100644 --- a/tests/serialize.rs +++ b/tests/serialize.rs @@ -1,4 +1,4 @@ -use serde_sjson::to_string; +use serde_sjson::{to_string, Error}; #[test] fn serialize_null() {