Skip to content

Commit

Permalink
Extract all links from paragraphs
Browse files Browse the repository at this point in the history
  • Loading branch information
dtolnay committed Dec 25, 2024
1 parent f15206a commit f006ea9
Show file tree
Hide file tree
Showing 12 changed files with 122 additions and 80 deletions.
31 changes: 18 additions & 13 deletions _src/container-attrs.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,23 +51,24 @@
- ##### `#[serde(tag = "type")]` {#tag}

On an enum: Use the internally tagged enum representation, with the given tag.
See [enum representations](enum-representations.md) for details on this
representation.
See [enum representations] for details on this representation.

On a struct with named fields: Serialize the struct's name (or value of
`serde(rename)`) as a field with the given key, in front of all the real
fields of the struct.

[enum representations]: enum-representations.md

- ##### `#[serde(tag = "t", content = "c")]` {#tag--content}

Use the adjacently tagged enum representation for this enum, with the given
field names for the tag and content. See [enum
representations](enum-representations.md) for details on this representation.
field names for the tag and content. See [enum representations] for details on
this representation.

- ##### `#[serde(untagged)]` {#untagged}

Use the untagged enum representation for this enum. See [enum
representations](enum-representations.md) for details on this representation.
Use the untagged enum representation for this enum. See [enum representations]
for details on this representation.

- ##### `#[serde(variant_identifier)]` {#variant_identifier}

Expand All @@ -78,11 +79,14 @@

- ##### `#[serde(field_identifier)]` {#field_identifier}

Identical to [`variant_identifier`](#variant_identifier), but also allows for
the last variant to be a newtype variant, which will be used if none of the
other variants match (similar to [`#[serde(other)]`](variant-attrs.md#other)).
Like `variant_identifier`, this forces the enum to always be represented as a
string, regardless of the underlying data format's representation of enums.
Identical to [`variant_identifier`], but also allows for the last variant to
be a newtype variant, which will be used if none of the other variants match
(similar to [`#[serde(other)]`]). Like `variant_identifier`, this forces the
enum to always be represented as a string, regardless of the underlying data
format's representation of enums.

[`variant_identifier`]: #variant_identifier
[`#[serde(other)`]: variant-attrs.md#other

- ##### `#[serde(bound = "T: MyTrait")]` {#bound}

Expand Down Expand Up @@ -110,8 +114,9 @@

- ##### `#[serde(remote = "...")]` {#remote}

This is used for deriving `Serialize` and `Deserialize` for [remote
types](remote-derive.md).
This is used for deriving `Serialize` and `Deserialize` for [remote types].

[remote types]: remote-derive.md

- ##### `#[serde(transparent)]` {#transparent}

Expand Down
8 changes: 5 additions & 3 deletions _src/custom-date-format.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
# Date in a custom format

This uses the [`chrono`](https://github.com/chronotope/chrono) crate to
serialize and deserialize JSON data containing a custom date format. The `with`
attribute is used to provide the logic for handling the custom representation.
This uses the [`chrono`] crate to serialize and deserialize JSON data containing
a custom date format. The `with` attribute is used to provide the logic for
handling the custom representation.

[`chrono`]: https://github.com/chronotope/chrono

!PLAYGROUND 2ef7c347c76b030fe7e8c59ce9efccd3
```rust
Expand Down
14 changes: 8 additions & 6 deletions _src/custom-serialization.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
# Custom serialization

Serde's [derive macro](derive.md) through `#[derive(Serialize, Deserialize)]`
provides reasonable default serialization behavior for structs and enums and it
can be customized to some extent using [attributes](attributes.md). For unusual
needs, Serde allows full customization of the serialization behavior by manually
implementing [`Serialize`] and [`Deserialize`] traits for your type.

Serde's [derive macro] through `#[derive(Serialize, Deserialize)]` provides
reasonable default serialization behavior for structs and enums and it can be
customized to some extent using [attributes]. For unusual needs, Serde allows
full customization of the serialization behavior by manually implementing
[`Serialize`] and [`Deserialize`] traits for your type.

[derive macro]: derive.md
[attributes]: attributes.md
[`Serialize`]: https://docs.rs/serde/1/serde/ser/trait.Serialize.html
[`Deserialize`]: https://docs.rs/serde/1/serde/de/trait.Deserialize.html

Expand Down
4 changes: 3 additions & 1 deletion _src/derive.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ would use to automatically derive implementations of the built-in `Clone`,
`Copy`, `Debug`, or other traits. It is able to generate implementations for
most structs and enums including ones with elaborate generic types or trait
bounds. On rare occasions, for an especially convoluted type you may need to
[implement the traits manually](custom-serialization.md).
[implement the traits manually].

[implement the traits manually]: custom-serialization.md

These derives require a Rust compiler version 1.31 or newer.

Expand Down
12 changes: 8 additions & 4 deletions _src/deserialize-struct.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Manually implementing Deserialize for a struct

Only when [derive](derive.md) is not getting the job done.
Only when [derive] is not getting the job done.

[derive]: derive.md

The `Deserialize` impl below corresponds to the following struct:

Expand All @@ -14,9 +16,11 @@ struct Duration {
# fn main() {}
```

Deserializing a struct is somewhat more complicated than [deserializing a
map](deserialize-map.md) in order to avoid allocating a String to hold the field
names. Instead there is a `Field` enum which is deserialized from a `&str`.
Deserializing a struct is somewhat more complicated than [deserializing a map]
in order to avoid allocating a String to hold the field names. Instead there is
a `Field` enum which is deserialized from a `&str`.

[deserializing a map]: deserialize-map.md

The implementation supports two possible ways that a struct may be represented
by a data format: as a seq like in Postcard, and as a map like in JSON.
Expand Down
27 changes: 16 additions & 11 deletions _src/examples.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
# Examples

**[Structs and enums in JSON](json.md)**: The representation chosen by
[`serde_json`](https://github.com/serde-rs/json) for structs and enums. Other
human-readable data formats are encouraged to follow an analogous approach where
possible.
[`serde_json`] for structs and enums. Other human-readable data formats are
encouraged to follow an analogous approach where possible.

[`serde_json`]: https://github.com/serde-rs/json

**[Enum representations](enum-representations.md)**: Externally tagged,
internally tagged, adjacently tagged, and untagged ways of representing an enum
Expand Down Expand Up @@ -43,17 +44,21 @@ the `#[serde(rename)]` attribute.
**[Discarding data](ignored-any.md)**: Using `IgnoredAny` to efficiently discard
data from a deserializer.

**[Transcode one format into another](transcode.md)**: Use the
[serde-transcode](https://github.com/sfackler/serde-transcode) crate to stream
input in one format to output in another format efficiently.
**[Transcode one format into another](transcode.md)**: Use the [serde-transcode]
crate to stream input in one format to output in another format efficiently.

[serde-transcode]: https://github.com/sfackler/serde-transcode

**[Deserialize either a string or a struct](string-or-struct.md)**: The
[`docker-compose.yml`](https://docs.docker.com/compose/compose-file/#/build)
configuration file has a "build" key which can be either a string or a struct.
[`docker-compose.yml`] configuration file has a "build" key which can be either
a string or a struct.

[`docker-compose.yml`]: https://docs.docker.com/compose/compose-file/#/build

**[Convert error types](convert-error.md)**: Map a Serde error from some format
into a Serde error for some other format using `Error::custom`.

**[Date in a custom format](custom-date-format.md)**: Handle a
[`chrono`](https://github.com/chronotope/chrono) `DateTime` formatted with a
custom string representation.
**[Date in a custom format](custom-date-format.md)**: Handle a [`chrono`]
`DateTime` formatted with a custom string representation.

[`chrono`]: https://github.com/chronotope/chrono
22 changes: 15 additions & 7 deletions _src/field-attrs.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,17 @@
- ##### `#[serde(rename = "name")]` {#rename}

Serialize and deserialize this field with the given name instead of its Rust
name. This is useful for [serializing fields as camelCase](attr-rename.md) or
serializing fields with names that are reserved Rust keywords.
name. This is useful for [serializing fields as camelCase] or serializing
fields with names that are reserved Rust keywords.

Allows specifying independent names for serialization vs deserialization:

- `#[serde(rename(serialize = "ser_name"))]`
- `#[serde(rename(deserialize = "de_name"))]`
- `#[serde(rename(serialize = "ser_name", deserialize = "de_name"))]`

[serializing fields as camelCase]: attr-rename.md

- ##### `#[serde(alias = "name")]` {#alias}

Deserialize this field from the given name *or* from its Rust name. May be
Expand All @@ -35,8 +37,10 @@
This removes one level of structure between the serialized representation and
the Rust data structure representation. It can be used for factoring common
keys into a shared structure, or for capturing remaining fields into a map
with arbitrary string keys. The [struct flattening](attr-flatten.md) page
provides some examples.
with arbitrary string keys. The [struct flattening] page provides some
examples.

[struct flattening]: attr-flatten.md

*Note:* this attribute is not supported in combination with structs that use
[`deny_unknown_fields`]. Neither the outer nor inner flattened struct should
Expand Down Expand Up @@ -94,7 +98,9 @@
- ##### `#[serde(borrow)]` and `#[serde(borrow = "'a + 'b + ...")]` {#borrow}

Borrow data for this field from the deserializer by using zero-copy
deserialization. See [this example](lifetimes.md#borrowing-data-in-a-derived-impl).
deserialization. See [this example][borrowing-data].

[borrowing-data]: lifetimes.md#borrowing-data-in-a-derived-impl

- ##### `#[serde(bound = "T: MyTrait")]` {#bound}

Expand All @@ -109,5 +115,7 @@

- ##### `#[serde(getter = "...")]` {#getter}

This is used when deriving `Serialize` for a [remote type](remote-derive.md)
that has one or more private fields.
This is used when deriving `Serialize` for a [remote type] that has one or
more private fields.

[remote type]: remote-derive.md
8 changes: 5 additions & 3 deletions _src/json.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

A Serde `Serializer` is responsible for selecting the convention by which Rust
structs and enums are represented in that format. Here are the conventions
selected by the [`serde_json`](https://github.com/serde-rs/json) data format.
For consistency, other human-readable formats are encouraged to develop
analogous conventions where possible.
selected by the [`serde_json`] data format. For consistency, other
human-readable formats are encouraged to develop analogous conventions where
possible.

[`serde_json`]: https://github.com/serde-rs/json

```rust
# #![allow(dead_code, unused_variables)]
Expand Down
13 changes: 8 additions & 5 deletions _src/string-or-struct.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
# Deserialize either a string or a struct

The [`docker-compose.yml`](https://docs.docker.com/compose/compose-file/#/build)
configuration file has a "build" key which can be either a string or a struct.
The [`docker-compose.yml`] configuration file has a "build" key which can be
either a string or a struct.

[`docker-compose.yml`]: https://docs.docker.com/compose/compose-file/#/build

```yaml
build: ./dir
Expand All @@ -19,9 +21,10 @@ The configuration file uses the same pattern in other places as well, typically
where a previously existing string field has been expanded to handle more
complex data.
We can use Rust's
[`FromStr`](https://doc.rust-lang.org/std/str/trait.FromStr.html) trait and
Serde's `deserialize_with` attribute to handle this pattern in a general way.
We can use Rust's [`FromStr`] trait and Serde's `deserialize_with` attribute to
handle this pattern in a general way.

[`FromStr`]: https://doc.rust-lang.org/std/str/trait.FromStr.html

```rust
use std::collections::BTreeMap as Map;
Expand Down
18 changes: 10 additions & 8 deletions _src/transcode.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
# Transcode one format into another

The [`serde-transcode`](https://github.com/sfackler/serde-transcode) crate
provides functionality to "transcode" from an arbitrary Serde `Deserializer` to
an arbitrary Serde `Serializer` without needing to collect the entire input into
an intermediate form in memory. This provides a fully general way to convert any
self-describing Serde data format into any other Serde data format in a
memory-efficient streaming way.
The [`serde-transcode`] crate provides functionality to "transcode" from an
arbitrary Serde `Deserializer` to an arbitrary Serde `Serializer` without
needing to collect the entire input into an intermediate form in memory. This
provides a fully general way to convert any self-describing Serde data format
into any other Serde data format in a memory-efficient streaming way.

[`serde-transcode`]: https://github.com/sfackler/serde-transcode

For example you could transcode a stream of JSON data into a stream of CBOR
data, or transcode unformatted JSON into its pretty-printed form.

This example implements the equivalent of Go's
[`json.Compact`](https://golang.org/pkg/encoding/json/#Compact) function which
This example implements the equivalent of Go's [`json.Compact`] function which
removes insignificant whitespace from a JSON string in a streaming way.

[`json.Compact`]: https://golang.org/pkg/encoding/json/#Compact

```rust
use std::io;

Expand Down
31 changes: 17 additions & 14 deletions _src/unit-testing.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,25 @@
# Unit testing

The [`serde_test`](https://docs.rs/serde_test) crate provides a convenient
concise way to write unit tests for implementations of `Serialize` and
`Deserialize`.
The [`serde_test`] crate provides a convenient concise way to write unit tests
for implementations of `Serialize` and `Deserialize`.

[`serde_test`]: https://docs.rs/serde_test

The `Serialize` impl for a value can be characterized by the sequence of
[`Serializer`](https://docs.rs/serde/1/serde/ser/trait.Serializer.html) calls
that are made in the course of serializing the value, so `serde_test` provides a
[`Token`](https://docs.rs/serde_test/1/serde_test/enum.Token.html) abstraction
which corresponds roughly to `Serializer` method calls. It provides an
`assert_ser_tokens` function to test that a value serializes into a particular
sequence of method calls, an `assert_de_tokens` function to test that a value
can be deserialized from a particular sequence of method calls, and an
`assert_tokens` function to test both directions. It also provides functions to
test expected failure conditions.
[`Serializer`] calls that are made in the course of serializing the value, so
`serde_test` provides a [`Token`] abstraction which corresponds roughly to
`Serializer` method calls. It provides an `assert_ser_tokens` function to test
that a value serializes into a particular sequence of method calls, an
`assert_de_tokens` function to test that a value can be deserialized from a
particular sequence of method calls, and an `assert_tokens` function to test
both directions. It also provides functions to test expected failure conditions.

[`Serializer`]: https://docs.rs/serde/1/serde/ser/trait.Serializer.html
[`Token`]: https://docs.rs/serde_test/1/serde_test/enum.Token.html

Here is an example from the [`linked-hash-map`] crate.

Here is an example from the
[`linked-hash-map`](https://github.com/contain-rs/linked-hash-map) crate.
[`linked-hash-map`]: https://github.com/contain-rs/linked-hash-map

```rust
# #[allow(unused_imports)]
Expand Down
14 changes: 9 additions & 5 deletions _src/variant-attrs.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,10 @@
- ##### `#[serde(borrow)]` and `#[serde(borrow = "'a + 'b + ...")]` {#borrow}

Borrow data for this field from the deserializer by using zero-copy
deserialization. See [this example](lifetimes.md#borrowing-data-in-a-derived-impl).
Only allowed on a newtype variant (a tuple variant with only one field).
deserialization. See [this example][borrowing-data]. Only allowed on a newtype
variant (a tuple variant with only one field).

[borrowing-data]: lifetimes.md#borrowing-data-in-a-derived-impl

- ##### `#[serde(other)]` {#other}

Expand All @@ -101,8 +103,10 @@

- ##### `#[serde(untagged)]` {#untagged}

Irrespective of the [enum representation](enum-representations.md), serialize
and deserialize this variant as untagged, i.e. simply as the variant's data
with no record of the variant name.
Irrespective of the [enum representation], serialize and deserialize this
variant as untagged, i.e. simply as the variant's data with no record of the
variant name.

Untagged variants must be ordered last in the enum definition.

[enum representations]: enum-representations.md

0 comments on commit f006ea9

Please sign in to comment.