Skip to main content

base_message/
combination.rs

1// Released under the MIT License.
2// Copyright, 2026, by Samuel Williams.
3
4//! How the instances of a field combine, as a type-level marker on each [`FieldType`](crate::FieldType).
5//!
6//! The marker decides how a section may declare the field: a [`Singleton`] as `Option<T>`, or as `T` when it is required, and a [`List`] or [`Separate`] field as `Vec<T>`. Declaring one the wrong way is a compile-time error. The markers are the only combinations: the traits here cannot be implemented outside this crate.
7
8mod sealed {
9    pub trait Sealed {}
10}
11
12/// A field that appears at most once, such as `Content-Length` or `Content-Type`: a second instance is an error, even with the same value.
13#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
14pub struct Singleton;
15
16/// A field whose instances form one comma-separated list, as RFC 9110 section 5.3 combines them, such as `Accept` or `Cache-Control`.
17#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
18pub struct List;
19
20/// A field whose instances are separate values that must not be combined, because a value can contain a comma, such as `Set-Cookie` or an email's `Received`.
21#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
22pub struct Separate;
23
24/// One of the combination markers: [`Singleton`], [`List`], or [`Separate`].
25pub trait Combination: sealed::Sealed {}
26
27impl sealed::Sealed for Singleton {}
28impl sealed::Sealed for List {}
29impl sealed::Sealed for Separate {}
30
31impl Combination for Singleton {}
32impl Combination for List {}
33impl Combination for Separate {}
34
35/// The combination of a field that appears at most once: [`Singleton`].
36#[diagnostic::on_unimplemented(
37    message = "a field type that can repeat cannot be declared as `Option<T>` or `T`",
38    label = "instances of this field type combine into several values",
39    note = "declare a list or separate field as `Vec<T>`, so that every value is kept"
40)]
41pub trait SingleValue: Combination {}
42
43impl SingleValue for Singleton {}
44
45/// The combinations that collect several values: [`List`] and [`Separate`].
46#[diagnostic::on_unimplemented(
47    message = "a singleton field type cannot be declared as `Vec<T>`",
48    label = "this field type appears at most once",
49    note = "declare a singleton field as `Option<T>`, or as `T` when it is required"
50)]
51pub trait MultipleValues: Combination {
52    /// Whether one instance holds a comma-separated list of elements.
53    const LIST: bool;
54}
55
56impl MultipleValues for List {
57    const LIST: bool = true;
58}
59
60impl MultipleValues for Separate {
61    const LIST: bool = false;
62}