Skip to content

Releases: sonalect/serde_markdown

v0.5.1

Choose a tag to compare

@amsokol amsokol released this 16 Oct 20:54
v0.5.1
7e0ff7c

Added

  • Ready for crates.io: keywords, categories, and the license text in both
    packages, a README for serde_markdown_derive, and docs.rs builds
    serde_markdown with every feature (the buffa and tokio modules).
    serde_markdown requires its own serde_markdown_derive by exact
    version.
  • CI builds and tests serde_markdown and serde_markdown_derive with
    the minimum Rust version, read from rust-version.

Changed

  • The minimum Rust version (rust-version) is 1.88 (it was 1.99.0), the
    oldest rustc that builds and tests the published crates.

  • The workspace takes its dependencies as caret ranges instead of exact
    pins (serde = "1.0.229", was "=1.0.229"), so a consumer is not held to
    one version of serde, buffa, tokio, or the format crates. Cargo.lock
    still fixes the versions this repository builds and tests; Renovate moves
    it within the ranges.

  • The README takes serde_markdown from crates.io
    (serde_markdown = "0.5") and links to GitHub by absolute URLs.

  • Dependencies: at least serde_json 1.0.154, syn 3.0.9, and tokio
    1.53.3.

  • Tooling: bazel_utils_* v0.4.0, Buf CLI v1.74.0, and
    bazel-contrib/setup-bazel 0.19.1 in CI. Buildifier, markdownlint, buf
    lint, and cargo audit now also run on Windows (amd64 and arm64), so every
    test but the doc tests runs on all six CI platforms; rules_rust cannot link
    doc tests on Windows (LNK1181).

v0.5.0

Choose a tag to compare

@amsokol amsokol released this 16 Oct 19:39
v0.5.0
dae8bdb

Added

  • Bazel test targets for the builds with only tokio and only buffa
    (serde_markdown_tokio_only, serde_markdown_buffa_only), next to the
    all-features, no_json, no_toml, no_yaml, and minimal builds.

Changed

  • Breaking: a key of the fields block that is named like a body field is
    ErrorKind::Type on read (the message names the key). Before, the key was
    dropped without a word, even from a type with deny_unknown_fields.
  • Breaking: a number that is not finite (.inf, .nan, inf, nan) is
    an error on read: ErrorKind::FrontMatter in the fields block,
    ErrorKind::Body in a structured body section. Before, it read as an
    absent value (None). The writer refuses such a number in every language
    (JSON used to write null): ErrorKind::FrontMatter in the fields block,
    ErrorKind::Body in a structured body section.
  • Breaking: the writer refuses a fields block that a reader would not
    read back as written: ErrorKind::FrontMatter with no source. In the bare
    layout this is a string holding a ---, fence, or HTML comment line, or
    any value whose encoding the reader would split or take for body; the
    message says to write it with FieldsLayout::Fenced.
  • Breaking: a Markdown::BODY_FIELDS name that the value never
    serializes (not even skipped) is ErrorKind::Type at write. A manual impl
    that named a missing field silently lost its section before.
  • Breaking: #[derive(Markdown)] rejects a body field that carries
    #[serde(skip)], skip_serializing, or skip_deserializing (compile
    error); use skip_serializing_if and default for an optional body field.
  • Breaking: the constructors Error::syntax, Error::front_matter,
    Error::body, Error::body_source, Error::type_error,
    Error::format_disabled, and Error::io are no longer public. Errors are
    made by the crate; read them with kind(), offset(), Display, and
    source(). To make one in your own Serialize or Deserialize code, use
    serde's Error::custom, which gives ErrorKind::Type. ? on an
    std::io::Error still converts, through From<io::Error>.
  • Breaking: ErrorKind is #[non_exhaustive]. A match on it needs a
    _ arm, so a kind added later does not break your build.
  • Format sniffing is strict. { is JSON. TOML is chosen only for a table
    header ([key], [[key]]) or a key = value first line whose value
    starts like a TOML value. A bare first slice that starts with [ and is
    not a table header (a Markdown link, a list) is body, with no decoder
    run; an unlabeled fence starting with [ is still JSON. A body-only
    document starting with [text](url) more or E = mc² is famous no longer
    fails with ErrorKind::FrontMatter.
  • A map key that is not a string (BTreeMap<u32, _>, i64, bool) reads
    in every language. Reading goes through serde_json::Value as the
    deserializer.
  • A Vec<u8> body is no longer decoded as a document to find out whether it
    is a list, unless it starts like one ([ or - after whitespace and #
    comment lines). A body-only document is no longer decoded as YAML unless
    its first line can start a mapping (it has a :, or starts with ?, {,
    !, &, *, or %). Results are the same; a 6 MB body is read and
    written about twice as fast.
  • The CommonMark parser stops after the last separator that splits the
    earlier body fields, so the verbatim last body field is not parsed. A 6 MB
    last field reads about three times as fast.
  • serde_markdown::PROTO_INCLUDE is for Cargo builds; under Bazel a build
    script takes the directory from the annotated filegroup (README, "The
    option in Bazel").
  • DESIGN.md, README, and ROADMAP.md match the code (sniffing, the fields
    fence, errors, tests, M15 and M16 done).

Removed

  • Breaking: serde_markdown::DESIGN, the constant holding the file name
    DESIGN.md. It had no use in code.

Fixed

  • A fenced fields block whose encoded text has a line of backticks (a YAML
    or TOML string holding a fence) closed early and read back with no error
    as different data. The fence is now longer than any such run.
  • FieldsLayout::Bare with TOML and every field absent wrote a stray
    --- and read back the body shifted. An empty bare block is now no block.
  • A bare TOML block that starts with a table ([meta]) was sniffed as JSON
    and failed to read back.
  • A newtype body field (struct Title(String)) was read through the YAML
    parser ("# Title\n\n- item" came back as "item"), and a char body
    field #, -, or ~ failed. Both are now raw section text; a newtype
    around a struct or a number is still read in the fence language.
  • A body-only document that needs an explicit empty fields block, written by
    a build without that language, wrote a block its own reader refuses. It
    is now ErrorKind::FormatDisabled at write.

v0.4.1

Choose a tag to compare

@amsokol amsokol released this 12 Oct 10:02
v0.4.1
705e298

Changed

  • Dependencies: syn =3.0.7, toml =1.1.8.

v0.4.0

Choose a tag to compare

@amsokol amsokol released this 07 Oct 17:30
v0.4.0
f996dc6

Added

  • Feature tokio (off by default) adds serde_markdown::tokio, the async
    twin of every function under the same name: to_string,
    to_string_with_format, to_string_with, to_vec, to_writer (tokio
    AsyncWrite), from_str, from_slice, from_reader (tokio
    AsyncRead). It writes and reads the same documents as the sync form. It
    is native: the same steps, with a cooperative yield between them when the
    task's budget is spent; no thread and no spawn_blocking, so an async
    caller awaits it as it is.
  • The runnable example example-tokio (rust/examples/tokio): the async
    form on a tokio runtime, with a file round-trip over tokio::fs and
    pages rendered in parallel tasks.

Changed

  • The README is rewritten for users of the crate: how to depend on it, the
    document shape, body fields, language and layout, errors, the async API
    (with a file round-trip over tokio::fs), and protobuf messages; the
    development notes moved to the end. Its examples are checked against the
    crate.
  • When a required body section and front-matter keys are both missing,
    the error is the first missing field in declaration order:
    ErrorKind::Type for a front-matter key. Before, the missing body
    section (ErrorKind::Body) was reported first.
  • markdown/options.proto, the (markdown.body) option, moved into the crate:
    rust/markdown/proto/markdown/options.proto. The import path is the same,
    markdown/options.proto. The Cargo dependency now brings the option too, so
    a consumer needs no second channel for it.
  • PROTO_INCLUDE points into the crate (<crate>/proto), so it works for a
    crate fetched alone, not only from a checkout of this repository.

Removed

  • The Bazel label @serde_markdown//proto/markdown:options.proto. A Bazel
    consumer drops its bazel_dep and git_override of serde_markdown and
    reaches the file through its crate_universe hub with an annotation
    (additive_build_file_content plus extra_aliased_targets); the README
    shows it. With one dependency the proto and the crate can no longer drift
    to different versions.
  • The fixtures crate serde_markdown-proto (not published) no longer carries
    the generated markdown.body extension constant.

Fixed

  • Enum fields read back. A field of an enum type (Serde's default,
    externally tagged form) failed to read with ErrorKind::Type, in the
    fields block and in a body section. Unit variants and variants with
    content now round-trip in YAML, JSON, and TOML; a unit variant in a body
    section is its raw name.
  • #[derive(Markdown)] follows the struct's #[serde(rename_all = "...")]
    (and rename_all(serialize = ..., deserialize = ...)) and drops the r#
    of a raw identifier. Before, a body field of such a struct was written
    into the fields block, with no error. A body field whose serialize and
    deserialize names differ is now a compile error.
  • A Vec<u8> body whose text reads as a YAML or JSON list ([1, 2],
    - a) reads back as its bytes; before, it read as the list's numbers or
    failed. A Vec<u8> whose text reads as an empty list ([]) is
    ErrorKind::Body on write, since it cannot be told from an empty list.
  • A body field with #[serde(default)] may be missing from the document:
    a field without a section is no longer handed to the value, so Serde
    applies its default (or None). A required one is still
    ErrorKind::Body.
  • A TOML date-time in the fields block (when = 1979-05-27T07:32:00Z)
    reads into a string or Timestamp field; before, ErrorKind::Type.
  • Built without the yaml feature, a document whose first slice is prose
    reads as body, and a body-only document is written with no empty fields
    block. Before, reading failed with ErrorKind::FormatDisabled and writing
    added an empty JSON or TOML block.
  • Leading --- lines are skipped in linear time. A document of many of
    them took quadratic time (40 000 lines: 1.4 s).
  • Every feature set builds and tests, none at all included.

v0.3.1

Choose a tag to compare

@amsokol amsokol released this 03 Oct 12:39
v0.3.1
09eb0d7

Fixed

  • FieldsLayout::Bare wrote a present but empty single body field
    (Some("")) without the --- that ends the fields, so it read back as
    None. The separator is now written whenever a body field is present.

v0.3.0

Choose a tag to compare

@amsokol amsokol released this 03 Oct 12:34
v0.3.0
717ed8e

Changed

  • The last body field is the rest of the document, verbatim: it is never
    parsed or trimmed, so it may hold top-level --- lines, setext underlines,
    tables, and fences. Before, such a body was written and then refused on read
    (found 2 sections) or cut.
  • Body text is verbatim in both directions: no line break is added at the end
    of the document or removed from a section. Documents written by 0.3.0 end
    with the last byte of the last section.
  • The presence of the last body field is its separator: no separator is
    None, a separator followed by nothing is Some(""), and "" after it is
    literal text. The "" convention for Some("") remains only for optional
    body fields that are not the last.
  • Front-matter keys are written in declaration order (proto field order for
    buffa messages) in YAML, JSON, and TOML, not alphabetically. No dependency
    was added.
  • A bare first slice that is not a mapping is body from its first byte; the
    leading whitespace and --- prefix is discarded only before fields.

Added

  • A body value that is not the last and holds a top-level --- line, an
    unclosed fence, or a trailing carriage return is ErrorKind::Body at write
    time, instead of a document that cannot be read back.

v0.2.3

Choose a tag to compare

@amsokol amsokol released this 02 Oct 10:37
v0.2.3
2ca164d

Fixed

  • A fenced code block inside a list item or a block quote was reported as an
    unclosed fence (Syntax) although its closing line was there: the check
    allowed at most three spaces before the closer on the raw line, and no >
    marker. The closer is now judged against the opener's column, after the
    container prefix. Bare YAML fields whose first key is a list read the rest
    of the mapping as that list item, so a multi-line string holding a fenced
    block was written by FieldsLayout::Bare and then refused on read.

v0.2.2

Choose a tag to compare

@amsokol amsokol released this 01 Oct 17:16
v0.2.2
4350285

Changed

  • Updated Rust toolchain and minimum supported Rust version from 1.98.1 to
    1.99.0 (Cargo rust-version and Bazel RUST_VERSION).
  • Added rust-toolchain.toml to pin the Rust toolchain for Cargo builds.

v0.2.1

Choose a tag to compare

@amsokol amsokol released this 27 Sep 14:27
v0.2.1
a29ef8d

Changed

  • Updated all bazel_utils_* modules to v0.2.11.
  • Updated bazel_utils_* git remotes to use sonalect forks.
  • Protobuf well-known types now sourced locally via proto/third_party instead
    of remote Buf dependency.
  • Updated buf.yaml to remove remote wellknowntypes dependency.

v0.2.0

Choose a tag to compare

@amsokol amsokol released this 27 Sep 11:10
v0.2.0
3af4607

Changed

  • Reorganized workspace structure: renamed rust/serde_markdown →
    rust/markdown, rust/serde_markdown_derive → rust/markdown_derive, and
    consolidated generated code into a new rust/proto module (replacing
    rust/generated).
  • Updated all bazel_utils_* modules to v0.2.10.
  • Updated protobuf to v36.2.