Repository: duesee/imap-codec (language: python)

Issue:
Types are rather difficult to find.
The idea of having a `command`, `response`, and `message` module sounds nice in theory but makes the types unintuitive to find. Do we have a better idea?

* [x] #234 


Discussion / hints:
What about:
https://doc.rust-lang.org/rustdoc/advanced-features.html#add-aliases-for-an-item-in-documentation-search

Seems very useful. Thanks for the hint!
I think the new (old :P) module layout from #235 is already an improvement.

@epilys: IMAP calls the things in "FETCH" "message data item" and the things in "STATUS" "status data item".

In imap-codec, I called them `FetchAttribute` and `StatusAttribute`. Now, I could try to make these types easier to find by using "{message,status} data item" aliases OR rename them to `MessageDataItem` and `StatusDataItem`. Or even something different? What do you think?

Fix patch:
diff --git a/benches/serialize_command.rs b/benches/serialize_command.rs
index e038b444..73ef7324 100644
--- a/benches/serialize_command.rs
+++ b/benches/serialize_command.rs
@@ -4,7 +4,7 @@ use criterion::{black_box, criterion_group, criterion_main, Criterion};
 use imap_codec::{
     codec::Encode,
     command::{Command, CommandBody},
-    fetch::{FetchAttribute, MacroOrFetchAttributes},
+    fetch::{MacroOrMessageDataItemNames, MessageDataItemName},
     section::Section,
 };
 
@@ -17,16 +17,16 @@ fn criterion_benchmark(c: &mut Criterion) {
         "C123",
         CommandBody::fetch(
             "1:*,2,3,4,5,6,7,8,9",
-            MacroOrFetchAttributes::FetchAttributes(vec![
-                FetchAttribute::Rfc822Size,
-                FetchAttribute::BodyExt {
+            MacroOrMessageDataItemNames::MessageDataItemNames(vec![
+                MessageDataItemName::Rfc822Size,
+                MessageDataItemName::BodyExt {
                     section: Some(Section::Text(None)),
                     peek: true,
                     partial: Some((1, NonZeroU32::try_from(100).unwrap())),
                 },
-                FetchAttribute::BodyStructure,
-                FetchAttribute::Body,
-                FetchAttribute::Envelope,
+                MessageDataItemName::BodyStructure,
+                MessageDataItemName::Body,
+                MessageDataItemName::Envelope,
             ]),
             true,
         )
diff --git a/imap-types/src/command.rs b/imap-types/src/command.rs
index 6ed32c4d..f0f5d046 100644
--- a/imap-types/src/command.rs
+++ b/imap-types/src/command.rs
@@ -20,13 +20,13 @@ use crate::{
     auth::AuthMechanism,
     core::{AString, Charset, Literal, Tag},
     datetime::DateTime,
-    fetch::MacroOrFetchAttributes,
+    fetch::MacroOrMessageDataItemNames,
     flag::{Flag, StoreResponse, StoreType},
     mailbox::{ListMailbox, Mailbox},
     search::SearchKey,
     secret::Secret,
     sequence::SequenceSet,
-    status::StatusAttribute,
+    status::StatusDataItemName,
 };
 #[cfg(feature = "ext_enable")]
 use crate::{core::NonEmptyVec, extensions::enable::CapabilityEnable};
@@ -779,7 +779,7 @@ pub enum CommandBody<'a> {
     ///   reasonable performance.
     Status {
         mailbox: Mailbox<'a>,
-        attributes: Cow<'a, [StatusAttribute]>,
+        item_names: Cow<'a, [StatusDataItemName]>,
     },
 
     /// 6.3.11. APPEND Command
@@ -997,7 +997,7 @@ pub enum CommandBody<'a> {
     ///   safely ignore the newly transmitted envelope.
     Fetch {
         sequence_set: SequenceSet,
-        attributes: MacroOrFetchAttributes<'a>,
+        macro_or_item_names: MacroOrMessageDataItemNames<'a>,
         uid: bool,
     },
 
@@ -1451,14 +1451,16 @@ impl<'a> CommandBody<'a> {
         })
     }
 
-    pub fn status<M, A>(mailbox: M, attributes: A) -> Result<Self, M::Error>
+    pub fn status<M, I>(mailbox: M, item_names: I) -> Result<Self, M::Error>
     where
         M: TryInto<Mailbox<'a>>,
-        A: Into<Cow<'a, [StatusAttribute]>>,
+        I: Into<Cow<'a, [StatusDataItemName]>>,
     {
+        let mailbox = mailbox.try_into()?;
+
         Ok(CommandBody::Status {
-            mailbox: mailbox.try_into()?,
-            attributes: attributes.into(),
+            mailbox,
+            item_names: item_names.into(),
         })
     }
 
@@ -1488,16 +1490,16 @@ impl<'a> CommandBody<'a> {
         }
     }
 
-    pub fn fetch<S, I>(sequence_set: S, attributes: I, uid: bool) -> Result<Self, S::Error>
+    pub fn fetch<S, I>(sequence_set: S, macro_or_item_names: I, uid: bool) -> Result<Self, S::Error>
     where
         S: TryInto<SequenceSet>,
-        I: Into<MacroOrFetchAttributes<'a>>,
+        I: Into<MacroOrMessageDataItemNames<'a>>,
     {
         let sequence_set = sequence_set.try_into()?;
 
         Ok(CommandBody::Fetch {
             sequence_set,
-            attributes: attributes.into(),
+            macro_or_item_names: macro_or_item_names.into(),
             uid,
         })
     }
@@ -1637,14 +1639,14 @@ mod tests {
         auth::AuthMechanism,
         core::{AString, Charset, IString, Literal},
         datetime::DateTime,
-        fetch::{FetchAttribute, Macro, MacroOrFetchAttributes},
+        fetch::{Macro, MacroOrMessageDataItemNames, MessageDataItemName},
         flag::{Flag, StoreType},
         mailbox::{ListMailbox, Mailbox},
         search::SearchKey,
         secret::Secret,
         section::{Part, Section},
         sequence::{SeqOrUid, Sequence, SequenceSet},
-        status::StatusAttribute,
+        status::StatusDataItemName,
     };
     #[cfg(feature = "ext_enable")]
     use crate::{
@@ -1704,7 +1706,7 @@ mod tests {
                 ListMailbox::String(IString::Quoted("\x7f".try_into().unwrap())),
             )
             .unwrap(),
-            CommandBody::status("inbox", vec![StatusAttribute::Messages]).unwrap(),
+            CommandBody::status("inbox", vec![StatusDataItemName::Messages]).unwrap(),
             CommandBody::append(
                 "inbox",
                 vec![],
@@ -1779,7 +1781,7 @@ mod tests {
             ),
             CommandBody::fetch(
                 "1",
-                vec![FetchAttribute::BodyExt {
+                vec![MessageDataItemName::BodyExt {
                     partial: None,
                     section: Some(Section::Part(Part(
                         vec![1.try_into().unwrap(), 1.try_into().unwrap()]
@@ -1904,7 +1906,7 @@ mod tests {
             (
                 CommandBody::Status {
                     mailbox: Mailbox::Inbox,
-                    attributes: vec![].into(),
+                    item_names: vec![].into(),
                 },
                 "STATUS",
             ),
@@ -1931,7 +1933,7 @@ mod tests {
             (
                 CommandBody::Fetch {
                     sequence_set: SequenceSet::try_from(1u32).unwrap(),
-                    attributes: MacroOrFetchAttributes::Macro(Macro::Full),
+                    macro_or_item_names: MacroOrMessageDataItemNames::Macro(Macro::Full),
                     uid: true,
                 },
                 "FETCH",
diff --git a/imap-types/src/extensions/quota.rs b/imap-types/src/extensions/quota.rs
index 8d995921..8cecb146 100644
--- a/imap-types/src/extensions/quota.rs
+++ b/imap-types/src/extensions/quota.rs
@@ -23,15 +23,15 @@
 //!
 //!     - [`Code::OverQuota`](crate::response::Code::OverQuota)
 //!
-//! * [`StatusAttribute`](crate::status::StatusAttribute) with new variants:
+//! * [`StatusDataItemName`](crate::status::StatusDataItemName) with new variants:
 //!
-//!     - [`StatusAttribute::Deleted`](crate::status::StatusAttribute::Deleted)
-//!     - [`StatusAttribute::DeletedStorage`](crate::status::StatusAttribute::DeletedStorage)
+//!     - [`StatusDataItemName::Deleted`](crate::status::StatusDataItemName::Deleted)
+//!     - [`StatusDataItemName::DeletedStorage`](crate::status::StatusDataItemName::DeletedStorage)
 //!
-//! * [`StatusAttributeValue`](crate::status::StatusAttributeValue) with new variants:
+//! * [`StatusDataItem`](crate::status::StatusDataItem) with new variants:
 //!
-//!     - [`StatusAttributeValue::Deleted`](crate::status::StatusAttributeValue::Deleted)
-//!     - [`StatusAttributeValue::DeletedStorage`](crate::status::StatusAttributeValue::DeletedStorage)
+//!     - [`StatusDataItem::Deleted`](crate::status::StatusDataItem::Deleted)
+//!     - [`StatusDataItem::DeletedStorage`](crate::status::StatusDataItem::DeletedStorage)
 
 use std::borrow::Cow;
 
diff --git a/imap-types/src/fetch.rs b/imap-types/src/fetch.rs
index 18939e6c..3d362608 100644
--- a/imap-types/src/fetch.rs
+++ b/imap-types/src/fetch.rs
@@ -12,27 +12,23 @@ use crate::{
     section::Section,
 };
 
-/// There are three macros which specify commonly-used sets of data
-/// items, and can be used instead of data items.
+/// Shorthands for commonly-used message data items.
 #[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
 #[cfg_attr(feature = "bounded-static", derive(ToStatic))]
 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub enum Macro {
-    /// `ALL` Macro equivalent to:
-    ///   `(FLAGS INTERNALDATE RFC822.SIZE ENVELOPE)`
-    All,
-    /// `FAST` Macro equivalent to:
-    ///   `(FLAGS INTERNALDATE RFC822.SIZE)`
+    /// Shorthand for `(FLAGS INTERNALDATE RFC822.SIZE)`.
     Fast,
-    /// `FULL` Macro equivalent to:
-    ///   `(FLAGS INTERNALDATE RFC822.SIZE ENVELOPE BODY)`
+    /// Shorthand for `(FLAGS INTERNALDATE RFC822.SIZE ENVELOPE)`.
+    All,
+    /// Shorthand for `(FLAGS INTERNALDATE RFC822.SIZE ENVELOPE BODY)`.
     Full,
 }
 
 impl Macro {
-    pub fn expand(&self) -> Vec<FetchAttribute> {
-        use FetchAttribute::*;
+    pub fn expand(&self) -> Vec<MessageDataItemName> {
+        use MessageDataItemName::*;
 
         match self {
             Self::All => vec![Flags, InternalDate, Rfc822Size, Envelope],
@@ -42,44 +38,51 @@ impl Macro {
     }
 }
 
+/// Either a macro or a list of message data items.
+///
 /// A macro must be used by itself, and not in conjunction with other macros or data items.
 #[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
 #[cfg_attr(feature = "bounded-static", derive(ToStatic))]
 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub enum MacroOrFetchAttributes<'a> {
+pub enum MacroOrMessageDataItemNames<'a> {
     Macro(Macro),
-    FetchAttributes(Vec<FetchAttribute<'a>>),
+    MessageDataItemNames(Vec<MessageDataItemName<'a>>),
 }
 
-impl<'a> From<Macro> for MacroOrFetchAttributes<'a> {
+impl<'a> From<Macro> for MacroOrMessageDataItemNames<'a> {
     fn from(m: Macro) -> Self {
-        MacroOrFetchAttributes::Macro(m)
+        MacroOrMessageDataItemNames::Macro(m)
     }
 }
 
-impl<'a> From<Vec<FetchAttribute<'a>>> for MacroOrFetchAttributes<'a> {
-    fn from(attributes: Vec<FetchAttribute<'a>>) -> Self {
-        MacroOrFetchAttributes::FetchAttributes(attributes)
+impl<'a> From<Vec<MessageDataItemName<'a>>> for MacroOrMessageDataItemNames<'a> {
+    fn from(item_names: Vec<MessageDataItemName<'a>>) -> Self {
+        MacroOrMessageDataItemNames::MessageDataItemNames(item_names)
     }
 }
 
-/// The currently defined data items that can be fetched are:
+/// Message data item name used to request a message data item.
 #[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
 #[cfg_attr(feature = "bounded-static", derive(ToStatic))]
 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub enum FetchAttribute<'a> {
-    /// `BODY`
-    ///
+#[doc(alias = "FetchAttribute")]
+pub enum MessageDataItemName<'a> {
     /// Non-extensible form of `BODYSTRUCTURE`.
+    ///
+    /// ```imap
+    /// BODY
+    /// ```
     Body,
 
-    /// `BODY[<section>]<<partial>>`
+    /// The text of a particular body section.
+    ///
+    /// ```imap
+    /// BODY[<section>]<<partial>>
+    /// ```
     BodyExt {
-        /// The text of a particular body section.  The section
-        /// specification is a set of zero or more part specifiers
-        /// delimited by periods.
+        /// The section specification is a set of zero or more part specifiers delimited by periods.
         ///
         /// An empty section specification refers to the entire message, including the header.
         ///
@@ -123,83 +126,107 @@ pub enum FetchAttribute<'a> {
         peek: bool,
     },
 
-    /// `BODYSTRUCTURE`
+    /// The [MIME-IMB] body structure of a message.
     ///
-    /// The [MIME-IMB] body structure of the message.  This is computed
-    /// by the server by parsing the [MIME-IMB] header fields in the
-    /// [RFC-2822] header and [MIME-IMB] headers.
+    /// This is computed by the server by parsing the [MIME-IMB] header fields in the [RFC-2822]
+    /// header and [MIME-IMB] headers.
+    ///
+    /// ```imap
+    /// BODYSTRUCTURE
+    /// ```
     BodyStructure,
 
-    /// `ENVELOPE`
+    /// The envelope structure of a message.
+    ///
+    /// This is computed by the server by parsing the [RFC-2822] header into the component parts,
+    /// defaulting various fields as necessary.
     ///
-    /// The envelope structure of the message.  This is computed by the
-    /// server by parsing the [RFC-2822] header into the component
-    /// parts, defaulting various fields as necessary.
+    /// ```imap
+    /// ENVELOPE
+    /// ```
     Envelope,
 
-    /// `FLAGS`
+    /// The flags that are set for a message.
     ///
-    /// The flags that are set for this message.
+    /// ```imap
+    /// FLAGS
+    /// ```
     Flags,
 
-    /// `INTERNALDATE`
+    /// The internal date of a message.
     ///
-    /// The internal date of the message.
+    /// ```imap
+    /// INTERNALDATE
+    /// ```
     InternalDate,
 
-    /// `RFC822`
+    /// Functionally equivalent to `BODY[]`.
+    ///
+    /// Differs in the syntax of the resulting untagged FETCH data (`RFC822` is returned).
+    ///
+    /// ```imap
+    /// RFC822
+    /// ```
+    ///
+    /// Note: `BODY[]` is constructed as ...
     ///
-    /// Functionally equivalent to `BODY[]`, differing in the syntax of
-    /// the resulting untagged FETCH data (`RFC822` is returned).
+    /// ```rust
+    /// # use imap_types::fetch::MessageDataItemName;
+    /// MessageDataItemName::BodyExt {
+    ///     section: None,
+    ///     partial: None,
+    ///     peek: false,
+    /// };
+    /// ```
     Rfc822,
 
-    /// `RFC822.HEADER`
+    /// Functionally equivalent to `BODY.PEEK[HEADER]`.
     ///
-    /// Functionally equivalent to `BODY.PEEK[HEADER]`, differing in the
-    /// syntax of the resulting untagged FETCH data (`RFC822.HEADER` is returned).
+    /// Differs in the syntax of the resulting untagged FETCH data (`RFC822.HEADER` is returned).
+    ///
+    /// ```imap
+    /// RFC822.HEADER
+    /// ```
     Rfc822Header,
 
-    /// `RFC822.SIZE`
+    /// The [RFC-2822] size of a message.
     ///
-    /// The [RFC-2822] size of the message.
+    /// ```imap
+    /// RFC822.SIZE
+    /// ```
     Rfc822Size,
 
-    /// `RFC822.TEXT`
+    /// Functionally equivalent to `BODY[TEXT]`.
     ///
-    /// Functionally equivalent to `BODY[TEXT]`, differing in the syntax
-    /// of the resulting untagged FETCH data (`RFC822.TEXT` is returned).
+    /// Differs in the syntax of the resulting untagged FETCH data (`RFC822.TEXT` is returned).
+    /// ```imap
+    /// RFC822.TEXT
+    /// ```
     Rfc822Text,
 
-    /// `UID`
+    /// The unique identifier for a message.
     ///
-    /// The unique identifier for the message.
+    /// ```imap
+    /// UID
+    /// ```
     Uid,
 }
 
-/// The current data items are:
+/// Message data item.
 #[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
 #[cfg_attr(feature = "bounded-static", derive(ToStatic))]
 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub enum FetchAttributeValue<'a> {
-    /// A form of BODYSTRUCTURE without extension data.
+#[doc(alias = "FetchAttributeValue")]
+pub enum MessageDataItem<'a> {
+    /// A form of `BODYSTRUCTURE` without extension data.
     ///
-    /// `BODY`
+    /// ```imap
+    /// BODY
+    /// ```
     Body(BodyStructure<'a>),
 
-    /// A string expressing the body contents of the specified section.
-    /// The string SHOULD be interpreted by the client according to the
-    /// content transfer encoding, body type, and subtype.
-    ///
-    /// If the origin octet is specified, this string is a substring of
-    /// the entire body contents, starting at that origin octet.  This
-    /// means that BODY[]<0> MAY be truncated, but BODY[] is NEVER
-    /// truncated.
-    ///
-    ///    Note: The origin octet facility MUST NOT be used by a server
-    ///    in a FETCH response unless the client specifically requested
-    ///    it by means of a FETCH of a BODY\[\<section\>\]\<\<partial\>\> data
-    ///    item.
+    /// The body contents of the specified section.
     ///
     /// 8-bit textual data is permitted if a \[CHARSET\] identifier is
     /// part of the body parameter parenthesized list for this section.
@@ -216,65 +243,98 @@ pub enum FetchAttributeValue<'a> {
     /// client.  To derive the original binary data, the client MUST
     /// decode the transfer encoded string.
     ///
-    /// `BODY[<section>]<<origin octet>>`
+    /// ```imap
+    /// BODY[<section>]<<origin octet>>
+    /// ```
     BodyExt {
+        /// The specified section.
         section: Option<Section<'a>>,
+        /// If the origin octet is specified, this string is a substring of
+        /// the entire body contents, starting at that origin octet.  This
+        /// means that `BODY[]<0>` MAY be truncated, but `BODY[]` is NEVER
+        /// truncated.
+        ///
+        ///    Note: The origin octet facility MUST NOT be used by a server
+        ///    in a FETCH response unless the client specifically requested
+        ///    it by means of a FETCH of a `BODY[<section>]<<partial>>` data
+        ///    item.
         origin: Option<u32>,
+        /// The string SHOULD be interpreted by the client according to the
+        /// content transfer encoding, body type, and subtype.
         data: NString<'a>,
     },
 
-    /// A parenthesized list that describes the [MIME-IMB] body
-    /// structure of a message.  This is computed by the server by
-    /// parsing the [MIME-IMB] header fields, defaulting various fields
-    /// as necessary.
+    /// The [MIME-IMB] body structure of a message.
     ///
-    /// `BODYSTRUCTURE`
+    /// This is computed by the server by parsing the [MIME-IMB] header fields, defaulting various
+    /// fields as necessary.
+    ///
+    /// ```imap
+    /// BODYSTRUCTURE
+    /// ```
     BodyStructure(BodyStructure<'a>),
 
-    /// A parenthesized list that describes the envelope structure of a
-    /// message.  This is computed by the server by parsing the
-    /// [RFC-2822] header into the component parts, defaulting various
-    /// fields as necessary.
+    /// The envelope structure of a message.
     ///
-    /// `ENVELOPE`
+    /// This is computed by the server by parsing the [RFC-2822] header into the component parts,
+    /// defaulting various fields as necessary.
+    ///
+    /// ```imap
+    /// ENVELOPE
+    /// ```
     Envelope(Envelope<'a>),
 
-    /// A parenthesized list of flags that are set for this message.
+    /// A list of flags that are set for a message.
     ///
-    /// `FLAGS`
+    /// ```imap
+    /// FLAGS
+    /// ```
     Flags(Vec<FlagFetch<'a>>),
 
-    /// A string representing the internal date of the message.
+    /// A string representing the internal date of a message.
     ///
-    /// `INTERNALDATE`
+    /// ```imap
+    /// INTERNALDATE
+    /// ```
     InternalDate(DateTime),
 
-    /// Equivalent to BODY[].
+    /// Equivalent to `BODY[]`.
     ///
-    /// `RFC822`
+    /// ```imap
+    /// RFC822
+    /// ```
     Rfc822(NString<'a>),
 
-    /// Equivalent to BODY\[HEADER\].  Note that this did not result in
-    /// \Seen being set, because RFC822.HEADER response data occurs as
-    /// a result of a FETCH of RFC822.HEADER.  BODY\[HEADER\] response
-    /// data occurs as a result of a FETCH of BODY\[HEADER\] (which sets
-    /// \Seen) or BODY.PEEK\[HEADER\] (which does not set \Seen).
+    /// Equivalent to `BODY[HEADER]`.
+    ///
+    /// Note that this did not result in `\Seen` being set, because `RFC822.HEADER` response data
+    /// occurs as a result of a `FETCH` of `RFC822.HEADER`. `BODY[HEADER]` response data occurs as a
+    /// result of a `FETCH` of `BODY[HEADER]` (which sets `\Seen`) or `BODY.PEEK[HEADER]` (which
+    /// does not set `\Seen`).
     ///
-    /// `RFC822.HEADER`
+    /// ```imap
+    /// RFC822.HEADER
+    /// ```
     Rfc822Header(NString<'a>),
 
-    /// A number expressing the [RFC-2822] size of the message.
+    /// A number expressing the [RFC-2822] size of a message.
     ///
-    /// `RFC822.SIZE`
+    /// ```imap
+    /// RFC822.SIZE
+    /// ```
     Rfc822Size(u32),
 
-    /// Equivalent to BODY\[TEXT\].
+    /// Equivalent to `BODY[TEXT]`.
     ///
-    /// `RFC822.TEXT`
+    /// ```imap
+    /// RFC822.TEXT
+    /// ```
     Rfc822Text(NString<'a>),
 
-    /// A number expressing the unique identifier of the message.
+    /// A number expressing the unique identifier of a message.
     ///
-    /// `UID`
+    /// ```imap
+    /// UID
+    /// ```
     Uid(NonZeroU32),
 }
diff --git a/imap-types/src/lib.rs b/imap-types/src/lib.rs
index 47241bcd..6497f107 100644
--- a/imap-types/src/lib.rs
+++ b/imap-types/src/lib.rs
@@ -63,16 +63,16 @@
 //! use imap_types::{
 //!     body::{BasicFields, Body, BodyStructure, SinglePartExtensionData, SpecificFields},
 //!     core::{IString, NString, NonEmptyVec},
-//!     fetch::FetchAttributeValue,
+//!     fetch::MessageDataItem,
 //!     response::{Data, Response},
 //! };
 //!
 //! let fetch = {
 //!     let data = Data::Fetch {
 //!         seq: NonZeroU32::new(42).unwrap(),
-//!         attributes: NonEmptyVec::try_from(vec![
-//!             FetchAttributeValue::Rfc822Size(1337),
-//!             FetchAttributeValue::Body(BodyStructure::Single {
+//!         items: NonEmptyVec::try_from(vec![
+//!             MessageDataItem::Rfc822Size(1337),
+//!             MessageDataItem::Body(BodyStructure::Single {
 //!                 body: Body {
 //!                     basic: BasicFields {
 //!                         parameter_list: vec![],
diff --git a/imap-types/src/response.rs b/imap-types/src/response.rs
index ef75c563..6407b579 100644
--- a/imap-types/src/response.rs
+++ b/imap-types/src/response.rs
@@ -23,10 +23,10 @@ use crate::extensions::literal::LiteralCapability;
 use crate::{
     auth::AuthMechanism,
     core::{impl_try_from, Atom, Charset, NonEmptyVec, QuotedChar, Tag, Text, TextError},
-    fetch::FetchAttributeValue,
+    fetch::MessageDataItem,
     flag::{Flag, FlagNameAttribute, FlagPerm},
     mailbox::Mailbox,
-    status::StatusAttributeValue,
+    status::StatusDataItem,
 };
 #[cfg(feature = "ext_quota")]
 use crate::{
@@ -408,7 +408,7 @@ pub enum Data<'a> {
         /// Name
         mailbox: Mailbox<'a>,
         /// Status parenthesized list
-        attributes: Cow<'a, [StatusAttributeValue]>,
+        items: Cow<'a, [StatusDataItem]>,
     },
 
     /// ### 7.2.5. SEARCH Response
@@ -526,10 +526,10 @@ pub enum Data<'a> {
     /// STORE command, as well as by unilateral server decision (e.g.,
     /// flag updates).
     Fetch {
-        /// Message SEQ or UID
+        /// Sequence number.
         seq: NonZeroU32,
-        /// Message data
-        attributes: NonEmptyVec<FetchAttributeValue<'a>>,
+        /// Message data items.
+        items: NonEmptyVec<MessageDataItem<'a>>,
     },
 
     #[cfg(feature = "ext_enable")]
@@ -594,24 +594,24 @@ impl<'a> Data<'a> {
         Ok(Self::Expunge(NonZeroU32::try_from(seq)?))
     }
 
-    pub fn fetch<I, A>(seq: I, attributes: A) -> Result<Self, FetchError<I::Error, A::Error>>
+    pub fn fetch<S, I>(seq: S, items: I) -> Result<Self, FetchError<S::Error, I::Error>>
     where
-        I: TryInto<NonZeroU32>,
-        A: TryInto<NonEmptyVec<FetchAttributeValue<'a>>>,
+        S: TryInto<NonZeroU32>,
+        I: TryInto<NonEmptyVec<MessageDataItem<'a>>>,
     {
-        Ok(Self::Fetch {
-            seq: seq.try_into().map_err(FetchError::SeqOrUid)?,
-            attributes: attributes.try_into().map_err(FetchError::Attributes)?,
-        })
+        let seq = seq.try_into().map_err(FetchError::SeqOrUid)?;
+        let items = items.try_into().map_err(FetchError::InvalidItems)?;
+
+        Ok(Self::Fetch { seq, items })
     }
 }
 
 #[derive(Clone, Debug, Eq, Error, Hash, Ord, PartialEq, PartialOrd)]
-pub enum FetchError<I, A> {
+pub enum FetchError<S, I> {
     #[error("Invalid sequence or UID: {0:?}")]
-    SeqOrUid(I),
-    #[error("Invalid attributes: {0:?}")]
-    Attributes(A),
+    SeqOrUid(S),
+    #[error("Invalid items: {0:?}")]
+    InvalidItems(I),
 }
 
 /// ## 7.5. Server Responses - Command Continuation Request
@@ -1084,7 +1084,7 @@ mod tests {
     #[test]
     fn test_conversion_data() {
         let _ = Data::capability(vec![Capability::Imap4Rev1]).unwrap();
-        let _ = Data::fetch(1, vec![FetchAttributeValue::Rfc822Size(123)]).unwrap();
+        let _ = Data::fetch(1, vec![MessageDataItem::Rfc822Size(123)]).unwrap();
     }
 
     #[test]
diff --git a/imap-types/src/status.rs b/imap-types/src/status.rs
index de750761..ff244466 100644
--- a/imap-types/src/status.rs
+++ b/imap-types/src/status.rs
@@ -7,12 +7,13 @@ use bounded_static::ToStatic;
 #[cfg(feature = "serde")]
 use serde::{Deserialize, Serialize};
 
-/// The currently defined status data items that can be requested.
+/// Status data item name used to request a status data item.
 #[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
 #[cfg_attr(feature = "bounded-static", derive(ToStatic))]
 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub enum StatusAttribute {
+#[doc(alias = "StatusAttribute")]
+pub enum StatusDataItemName {
     /// The number of messages in the mailbox.
     Messages,
 
@@ -43,12 +44,13 @@ pub enum StatusAttribute {
     HighestModSeq,
 }
 
-/// The currently defined status data items.
+/// Status data item.
 #[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
 #[cfg_attr(feature = "bounded-static", derive(ToStatic))]
 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub enum StatusAttributeValue {
+#[doc(alias = "StatusAttributeValue")]
+pub enum StatusDataItem {
     /// The number of messages in the mailbox.
     Messages(u32),
 
diff --git a/src/body.rs b/src/body.rs
index d9d45a73..0b9e7eca 100644
--- a/src/body.rs
+++ b/src/body.rs
@@ -553,7 +553,7 @@ mod tests {
     use super::*;
     use crate::{
         core::{Literal, Quoted},
-        fetch::FetchAttributeValue,
+        fetch::MessageDataItem,
         response::{Data, Response},
         testing::{kat_inverse_response, known_answer_test_encode},
     };
@@ -642,7 +642,7 @@ mod tests {
             b"".as_ref(),
             Response::Data(Data::Fetch {
                 seq: NonZeroU32::try_from(3372220415).unwrap(),
-                attributes: NonEmptyVec::from(FetchAttributeValue::BodyStructure(
+                items: NonEmptyVec::from(MessageDataItem::BodyStructure(
                     BodyStructure::Multi {
                         bodies: NonEmptyVec::from(BodyStructure::Multi {
                             bodies: NonEmptyVec::from(BodyStructure::Multi {
diff --git a/src/codec.rs b/src/codec.rs
index 915a1706..d758fbe0 100644
--- a/src/codec.rs
+++ b/src/codec.rs
@@ -51,7 +51,7 @@ mod tests {
     use crate::{
         command::{Command, CommandBody},
         core::{IString, Literal, NString, NonEmptyVec},
-        fetch::FetchAttributeValue,
+        fetch::MessageDataItem,
         mailbox::Mailbox,
         response::{Data, Greeting, GreetingKind, Response},
         testing::{kat_inverse_command, kat_inverse_greeting, kat_inverse_response},
@@ -134,7 +134,7 @@ mod tests {
                 b"",
                 Response::Data(Data::Fetch {
                     seq: NonZeroU32::new(1).unwrap(),
-                    attributes: NonEmptyVec::from(FetchAttributeValue::Rfc822(NString(Some(
+                    items: NonEmptyVec::from(MessageDataItem::Rfc822(NString(Some(
                         IString::Literal(Literal::try_from(b"hello".as_ref()).unwrap()),
                     )))),
                 }),
diff --git a/src/codec/decode.rs b/src/codec/decode.rs
index b1f0215f..c3be8a36 100644
--- a/src/codec/decode.rs
+++ b/src/codec/decode.rs
@@ -159,7 +159,7 @@ mod tests {
     use crate::{
         command::{Command, CommandBody},
         core::{IString, Literal, NString, NonEmptyVec},
-        fetch::FetchAttributeValue,
+        fetch::MessageDataItem,
         mailbox::Mailbox,
         response::{Data, Greeting, GreetingKind, Response},
     };
@@ -372,7 +372,7 @@ mod tests {
                     b"".as_ref(),
                     Response::Data(Data::Fetch {
                         seq: NonZeroU32::new(1).unwrap(),
-                        attributes: NonEmptyVec::from(FetchAttributeValue::Rfc822(NString(Some(
+                        items: NonEmptyVec::from(MessageDataItem::Rfc822(NString(Some(
                             IString::Literal(Literal::try_from(b"hello".as_ref()).unwrap()),
                         )))),
                     }),
diff --git a/src/codec/encode.rs b/src/codec/encode.rs
index c81d38f4..4c288693 100644
--- a/src/codec/encode.rs
+++ b/src/codec/encode.rs
@@ -19,7 +19,7 @@ use crate::{
     },
     datetime::{DateTime, NaiveDate},
     envelope::{Address, Envelope},
-    fetch::{FetchAttribute, FetchAttributeValue, Macro, MacroOrFetchAttributes},
+    fetch::{Macro, MacroOrMessageDataItemNames, MessageDataItem, MessageDataItemName},
     flag::{Flag, FlagExtension, FlagFetch, FlagNameAttribute, FlagPerm, StoreResponse, StoreType},
     mailbox::{ListCharString, ListMailbox, Mailbox, MailboxOther},
     response::{
@@ -28,7 +28,7 @@ use crate::{
     search::SearchKey,
     section::{Part, Section},
     sequence::{SeqOrUid, Sequence, SequenceSet},
-    status::{StatusAttribute, StatusAttributeValue},
+    status::{StatusDataItem, StatusDataItemName},
     utils::escape_quoted,
 };
 
@@ -333,14 +333,14 @@ impl<'a> Encoder for CommandBody<'a> {
             }
             CommandBody::Status {
                 mailbox,
-                attributes,
+                item_names,
             } => {
                 ctx.write_all(b"STATUS")?;
                 ctx.write_all(b" ")?;
                 mailbox.encode_ctx(ctx)?;
                 ctx.write_all(b" ")?;
                 ctx.write_all(b"(")?;
-                join_serializable(attributes, b" ", ctx)?;
+                join_serializable(item_names, b" ", ctx)?;
                 ctx.write_all(b")")
             }
             CommandBody::Append {
@@ -390,7 +390,7 @@ impl<'a> Encoder for CommandBody<'a> {
             }
             CommandBody::Fetch {
                 sequence_set,
-                attributes,
+                macro_or_item_names,
                 uid,
             } => {
                 if *uid {
@@ -401,7 +401,7 @@ impl<'a> Encoder for CommandBody<'a> {
 
                 sequence_set.encode_ctx(ctx)?;
                 ctx.write_all(b" ")?;
-                attributes.encode_ctx(ctx)
+                macro_or_item_names.encode_ctx(ctx)
             }
             CommandBody::Store {
                 sequence_set,
@@ -613,20 +613,20 @@ impl<'a> Encoder for ListCharString<'a> {
     }
 }
 
-impl Encoder for StatusAttribute {
+impl Encoder for StatusDataItemName {
     fn encode_ctx(&self, ctx: &mut EncodeContext) -> std::io::Result<()> {
         match self {
-            StatusAttribute::Messages => ctx.write_all(b"MESSAGES"),
-            StatusAttribute::Recent => ctx.write_all(b"RECENT"),
-            StatusAttribute::UidNext => ctx.write_all(b"UIDNEXT"),
-            StatusAttribute::UidValidity => ctx.write_all(b"UIDVALIDITY"),
-            StatusAttribute::Unseen => ctx.write_all(b"UNSEEN"),
+            Self::Messages => ctx.write_all(b"MESSAGES"),
+            Self::Recent => ctx.write_all(b"RECENT"),
+            Self::UidNext => ctx.write_all(b"UIDNEXT"),
+            Self::UidValidity => ctx.write_all(b"UIDVALIDITY"),
+            Self::Unseen => ctx.write_all(b"UNSEEN"),
             #[cfg(feature = "ext_quota")]
-            StatusAttribute::Deleted => ctx.write_all(b"DELETED"),
+            Self::Deleted => ctx.write_all(b"DELETED"),
             #[cfg(feature = "ext_quota")]
-            StatusAttribute::DeletedStorage => ctx.write_all(b"DELETED-STORAGE"),
+            Self::DeletedStorage => ctx.write_all(b"DELETED-STORAGE"),
             #[cfg(feature = "ext_condstore_qresync")]
-            StatusAttribute::HighestModSeq => ctx.write_all(b"HIGHESTMODSEQ"),
+            Self::HighestModSeq => ctx.write_all(b"HIGHESTMODSEQ"),
         }
     }
 }
@@ -828,16 +828,16 @@ impl Encoder for NaiveDate {
     }
 }
 
-impl<'a> Encoder for MacroOrFetchAttributes<'a> {
+impl<'a> Encoder for MacroOrMessageDataItemNames<'a> {
     fn encode_ctx(&self, ctx: &mut EncodeContext) -> std::io::Result<()> {
         match self {
-            MacroOrFetchAttributes::Macro(m) => m.encode_ctx(ctx),
-            MacroOrFetchAttributes::FetchAttributes(attributes) => {
-                if attributes.len() == 1 {
-                    attributes[0].encode_ctx(ctx)
+            Self::Macro(m) => m.encode_ctx(ctx),
+            Self::MessageDataItemNames(item_names) => {
+                if item_names.len() == 1 {
+                    item_names[0].encode_ctx(ctx)
                 } else {
                     ctx.write_all(b"(")?;
-                    join_serializable(attributes.as_slice(), b" ", ctx)?;
+                    join_serializable(item_names.as_slice(), b" ", ctx)?;
                     ctx.write_all(b")")
                 }
             }
@@ -855,11 +855,11 @@ impl Encoder for Macro {
     }
 }
 
-impl<'a> Encoder for FetchAttribute<'a> {
+impl<'a> Encoder for MessageDataItemName<'a> {
     fn encode_ctx(&self, ctx: &mut EncodeContext) -> std::io::Result<()> {
         match self {
-            FetchAttribute::Body => ctx.write_all(b"BODY"),
-            FetchAttribute::BodyExt {
+            Self::Body => ctx.write_all(b"BODY"),
+            Self::BodyExt {
                 section,
                 partial,
                 peek,
@@ -879,15 +879,15 @@ impl<'a> Encoder for FetchAttribute<'a> {
 
                 Ok(())
             }
-            FetchAttribute::BodyStructure => ctx.write_all(b"BODYSTRUCTURE"),
-            FetchAttribute::Envelope => ctx.write_all(b"ENVELOPE"),
-            FetchAttribute::Flags => ctx.write_all(b"FLAGS"),
-            FetchAttribute::InternalDate => ctx.write_all(b"INTERNALDATE"),
-            FetchAttribute::Rfc822 => ctx.write_all(b"RFC822"),
-            FetchAttribute::Rfc822Header => ctx.write_all(b"RFC822.HEADER"),
-            FetchAttribute::Rfc822Size => ctx.write_all(b"RFC822.SIZE"),
-            FetchAttribute::Rfc822Text => ctx.write_all(b"RFC822.TEXT"),
-            FetchAttribute::Uid => ctx.write_all(b"UID"),
+            Self::BodyStructure => ctx.write_all(b"BODYSTRUCTURE"),
+            Self::Envelope => ctx.write_all(b"ENVELOPE"),
+            Self::Flags => ctx.write_all(b"FLAGS"),
+            Self::InternalDate => ctx.write_all(b"INTERNALDATE"),
+            Self::Rfc822 => ctx.write_all(b"RFC822"),
+            Self::Rfc822Header => ctx.write_all(b"RFC822.HEADER"),
+            Self::Rfc822Size => ctx.write_all(b"RFC822.SIZE"),
+            Self::Rfc822Text => ctx.write_all(b"RFC822.TEXT"),
+            Self::Uid => ctx.write_all(b"UID"),
         }
     }
 }
@@ -1185,14 +1185,11 @@ impl<'a> Encoder for Data<'a> {
                 ctx.write_all(b" ")?;
                 mailbox.encode_ctx(ctx)?;
             }
-            Data::Status {
-                mailbox,
-                attributes,
-            } => {
+            Data::Status { mailbox, items } => {
                 ctx.write_all(b"* STATUS ")?;
                 mailbox.encode_ctx(ctx)?;
                 ctx.write_all(b" (")?;
-                join_serializable(attributes, b" ", ctx)?;
+                join_serializable(items, b" ", ctx)?;
                 ctx.write_all(b")")?;
             }
             Data::Search(seqs) => {
@@ -1211,9 +1208,9 @@ impl<'a> Encoder for Data<'a> {
             Data::Exists(count) => write!(ctx, "* {count} EXISTS")?,
             Data::Recent(count) => write!(ctx, "* {count} RECENT")?,
             Data::Expunge(msg) => write!(ctx, "* {msg} EXPUNGE")?,
-            Data::Fetch { seq, attributes } => {
+            Data::Fetch { seq, items } => {
                 write!(ctx, "* {seq} FETCH (")?;
-                join_serializable(attributes.as_ref(), b" ", ctx)?;
+                join_serializable(items.as_ref(), b" ", ctx)?;
                 ctx.write_all(b")")?;
             }
             #[cfg(feature = "ext_enable")]
@@ -1273,7 +1270,7 @@ impl Encoder for QuotedChar {
     }
 }
 
-impl Encoder for StatusAttributeValue {
+impl Encoder for StatusDataItem {
     fn encode_ctx(&self, ctx: &mut EncodeContext) -> std::io::Result<()> {
         match self {
             Self::Messages(count) => {
@@ -1310,7 +1307,7 @@ impl Encoder for StatusAttributeValue {
     }
 }
 
-impl<'a> Encoder for FetchAttributeValue<'a> {
+impl<'a> Encoder for MessageDataItem<'a> {
     fn encode_ctx(&self, ctx: &mut EncodeContext) -> std::io::Result<()> {
         match self {
             Self::BodyExt {
@@ -1718,7 +1715,7 @@ mod tests {
         auth::AuthMechanism,
         command::{Command, CommandBody},
         core::{AString, Literal, NString, NonEmptyVec},
-        fetch::FetchAttributeValue,
+        fetch::MessageDataItem,
         response::{Data, Response},
         utils::escape_byte_string,
     };
@@ -1858,7 +1855,7 @@ mod tests {
             (
                 Response::Data(Data::Fetch {
                     seq: NonZeroU32::new(12345).unwrap(),
-                    attributes: NonEmptyVec::from(FetchAttributeValue::BodyExt {
+                    items: NonEmptyVec::from(MessageDataItem::BodyExt {
                         section: None,
                         origin: None,
                         data: NString::from(Literal::unvalidated(b"ABCDE".as_ref())),
@@ -1883,7 +1880,7 @@ mod tests {
             (
                 Response::Data(Data::Fetch {
                     seq: NonZeroU32::new(12345).unwrap(),
-                    attributes: NonEmptyVec::from(FetchAttributeValue::BodyExt {
+                    items: NonEmptyVec::from(MessageDataItem::BodyExt {
                         section: None,
                         origin: None,
                         data: NString::from(Literal::unvalidated_non_sync(b"ABCDE".as_ref())),
diff --git a/src/command.rs b/src/command.rs
index b01984bf..5e26afd6 100644
--- a/src/command.rs
+++ b/src/command.rs
@@ -35,7 +35,7 @@ use crate::{
     codec::IMAPResult,
     core::{astring, literal, tag_imap, AString},
     datetime::date_time,
-    fetch::{fetch_att, Macro, MacroOrFetchAttributes},
+    fetch::{fetch_att, Macro, MacroOrMessageDataItemNames},
     flag::{flag, flag_list, Flag, StoreResponse, StoreType},
     mailbox::{list_mailbox, mailbox},
     search::search,
@@ -245,13 +245,13 @@ pub fn status(input: &[u8]) -> IMAPResult<&[u8], CommandBody> {
         delimited(tag(b"("), separated_list0(sp, status_att), tag(b")")),
     ));
 
-    let (remaining, (_, _, mailbox, _, attributes)) = parser(input)?;
+    let (remaining, (_, _, mailbox, _, item_names)) = parser(input)?;
 
     Ok((
         remaining,
         CommandBody::Status {
             mailbox,
-            attributes: attributes.into(),
+            item_names: item_names.into(),
         },
     ))
 }
@@ -443,34 +443,34 @@ pub fn fetch(input: &[u8]) -> IMAPResult<&[u8], CommandBody> {
         sp,
         alt((
             value(
-                MacroOrFetchAttributes::Macro(Macro::All),
+                MacroOrMessageDataItemNames::Macro(Macro::All),
                 tag_no_case(b"ALL"),
             ),
             value(
-                MacroOrFetchAttributes::Macro(Macro::Fast),
+                MacroOrMessageDataItemNames::Macro(Macro::Fast),
                 tag_no_case(b"FAST"),
             ),
             value(
-                MacroOrFetchAttributes::Macro(Macro::Full),
+                MacroOrMessageDataItemNames::Macro(Macro::Full),
                 tag_no_case(b"FULL"),
             ),
             map(fetch_att, |fetch_att| {
-                MacroOrFetchAttributes::FetchAttributes(vec![fetch_att])
+                MacroOrMessageDataItemNames::MessageDataItemNames(vec![fetch_att])
             }),
             map(
                 delimited(tag(b"("), separated_list0(sp, fetch_att), tag(b")")),
-                MacroOrFetchAttributes::FetchAttributes,
+                MacroOrMessageDataItemNames::MessageDataItemNames,
             ),
         )),
     ));
 
-    let (remaining, (_, _, sequence_set, _, attributes)) = parser(input)?;
+    let (remaining, (_, _, sequence_set, _, macro_or_item_names)) = parser(input)?;
 
     Ok((
         remaining,
         CommandBody::Fetch {
             sequence_set,
-            attributes,
+            macro_or_item_names,
             uid: false,
         },
     ))
@@ -564,7 +564,7 @@ mod tests {
     use crate::codec::Encode;
     #[cfg(feature = "ext_sasl_ir")]
     use crate::core::Tag;
-    use crate::{fetch::FetchAttribute, section::Section};
+    use crate::{fetch::MessageDataItemName, section::Section};
 
     #[test]
     fn test_parse_fetch() {
@@ -574,18 +574,18 @@ mod tests {
     #[test]
     fn test_parse_fetch_att() {
         let tests = [
-            (FetchAttribute::Envelope, "ENVELOPE???"),
-            (FetchAttribute::Flags, "FLAGS???"),
-            (FetchAttribute::InternalDate, "INTERNALDATE???"),
-            (FetchAttribute::Rfc822, "RFC822???"),
-            (FetchAttribute::Rfc822Header, "RFC822.HEADER???"),
-            (FetchAttribute::Rfc822Size, "RFC822.SIZE???"),
-            (FetchAttribute::Rfc822Text, "RFC822.TEXT???"),
-            (FetchAttribute::Body, "BODY???"),
-            (FetchAttribute::BodyStructure, "BODYSTRUCTURE???"),
-            (FetchAttribute::Uid, "UID???"),
+            (MessageDataItemName::Envelope, "ENVELOPE???"),
+            (MessageDataItemName::Flags, "FLAGS???"),
+            (MessageDataItemName::InternalDate, "INTERNALDATE???"),
+            (MessageDataItemName::Rfc822, "RFC822???"),
+            (MessageDataItemName::Rfc822Header, "RFC822.HEADER???"),
+            (MessageDataItemName::Rfc822Size, "RFC822.SIZE???"),
+            (MessageDataItemName::Rfc822Text, "RFC822.TEXT???"),
+            (MessageDataItemName::Body, "BODY???"),
+            (MessageDataItemName::BodyStructure, "BODYSTRUCTURE???"),
+            (MessageDataItemName::Uid, "UID???"),
             (
-                FetchAttribute::BodyExt {
+                MessageDataItemName::BodyExt {
                     partial: None,
                     peek: false,
                     section: None,
@@ -593,7 +593,7 @@ mod tests {
                 "BODY[]???",
             ),
             (
-                FetchAttribute::BodyExt {
+                MessageDataItemName::BodyExt {
                     partial: None,
                     peek: true,
                     section: None,
@@ -601,7 +601,7 @@ mod tests {
                 "BODY.PEEK[]???",
             ),
             (
-                FetchAttribute::BodyExt {
+                MessageDataItemName::BodyExt {
                     partial: None,
                     peek: true,
                     section: Some(Section::Text(None)),
@@ -609,7 +609,7 @@ mod tests {
                 "BODY.PEEK[TEXT]???",
             ),
             (
-                FetchAttribute::BodyExt {
+                MessageDataItemName::BodyExt {
                     partial: Some((42, NonZeroU32::try_from(1337).unwrap())),
                     peek: true,
                     section: Some(Section::Text(None)),
diff --git a/src/extensions/quota.rs b/src/extensions/quota.rs
index 5d417e58..7e242573 100644
--- a/src/extensions/quota.rs
+++ b/src/extensions/quota.rs
@@ -228,7 +228,7 @@ mod tests {
         core::{IString, Tag},
         mailbox::Mailbox,
         response::{Capability, Code, Response, Status},
-        status::{StatusAttribute, StatusAttributeValue},
+        status::{StatusDataItem, StatusDataItemName},
         testing::{kat_inverse_command, kat_inverse_response},
     };
 
@@ -413,9 +413,9 @@ mod tests {
             CommandBody::status(
                 "inbox",
                 vec![
-                    StatusAttribute::Messages,
-                    StatusAttribute::Deleted,
-                    StatusAttribute::DeletedStorage,
+                    StatusDataItemName::Messages,
+                    StatusDataItemName::Deleted,
+                    StatusDataItemName::DeletedStorage,
                 ],
             )
             .unwrap()
@@ -582,10 +582,10 @@ mod tests {
                 b"",
                 Response::Data(Data::Status {
                     mailbox: Mailbox::Inbox,
-                    attributes: vec![
-                        StatusAttributeValue::Messages(12),
-                        StatusAttributeValue::Deleted(4),
-                        StatusAttributeValue::DeletedStorage(8),
+                    items: vec![
+                        StatusDataItem::Messages(12),
+                        StatusDataItem::Deleted(4),
+                        StatusDataItem::DeletedStorage(8),
                     ]
                     .into(),
                 }),
diff --git a/src/fetch.rs b/src/fetch.rs
index 374cfa40..29881d21 100644
--- a/src/fetch.rs
+++ b/src/fetch.rs
@@ -31,12 +31,18 @@ use crate::{
 ///              "UID" /
 ///              "BODY" section ["<" number "." nz-number ">"] /
 ///              "BODY.PEEK" section ["<" number "." nz-number ">"]`
-pub fn fetch_att(input: &[u8]) -> IMAPResult<&[u8], FetchAttribute> {
+pub fn fetch_att(input: &[u8]) -> IMAPResult<&[u8], MessageDataItemName> {
     alt((
-        value(FetchAttribute::Envelope, tag_no_case(b"ENVELOPE")),
-        value(FetchAttribute::Flags, tag_no_case(b"FLAGS")),
-        value(FetchAttribute::InternalDate, tag_no_case(b"INTERNALDATE")),
-        value(FetchAttribute::BodyStructure, tag_no_case(b"BODYSTRUCTURE")),
+        value(MessageDataItemName::Envelope, tag_no_case(b"ENVELOPE")),
+        value(MessageDataItemName::Flags, tag_no_case(b"FLAGS")),
+        value(
+            MessageDataItemName::InternalDate,
+            tag_no_case(b"INTERNALDATE"),
+        ),
+        value(
+            MessageDataItemName::BodyStructure,
+            tag_no_case(b"BODYSTRUCTURE"),
+        ),
         map(
             tuple((
                 tag_no_case(b"BODY.PEEK"),
@@ -47,7 +53,7 @@ pub fn fetch_att(input: &[u8]) -> IMAPResult<&[u8], FetchAttribute> {
                     tag(b">"),
                 )),
             )),
-            |(_, section, byterange)| FetchAttribute::BodyExt {
+            |(_, section, byterange)| MessageDataItemName::BodyExt {
                 section,
                 partial: byterange.map(|(start, _, end)| (start, end)),
                 peek: true,
@@ -63,25 +69,28 @@ pub fn fetch_att(input: &[u8]) -> IMAPResult<&[u8], FetchAttribute> {
                     tag(b">"),
                 )),
             )),
-            |(_, section, byterange)| FetchAttribute::BodyExt {
+            |(_, section, byterange)| MessageDataItemName::BodyExt {
                 section,
                 partial: byterange.map(|(start, _, end)| (start, end)),
                 peek: false,
             },
         ),
-        value(FetchAttribute::Body, tag_no_case(b"BODY")),
-        value(FetchAttribute::Uid, tag_no_case(b"UID")),
-        value(FetchAttribute::Rfc822Header, tag_no_case(b"RFC822.HEADER")),
-        value(FetchAttribute::Rfc822Size, tag_no_case(b"RFC822.SIZE")),
-        value(FetchAttribute::Rfc822Text, tag_no_case(b"RFC822.TEXT")),
-        value(FetchAttribute::Rfc822, tag_no_case(b"RFC822")),
+        value(MessageDataItemName::Body, tag_no_case(b"BODY")),
+        value(MessageDataItemName::Uid, tag_no_case(b"UID")),
+        value(
+            MessageDataItemName::Rfc822Header,
+            tag_no_case(b"RFC822.HEADER"),
+        ),
+        value(MessageDataItemName::Rfc822Size, tag_no_case(b"RFC822.SIZE")),
+        value(MessageDataItemName::Rfc822Text, tag_no_case(b"RFC822.TEXT")),
+        value(MessageDataItemName::Rfc822, tag_no_case(b"RFC822")),
     ))(input)
 }
 
 /// `msg-att = "("
 ///            (msg-att-dynamic / msg-att-static) *(SP (msg-att-dynamic / msg-att-static))
 ///            ")"`
-pub fn msg_att(input: &[u8]) -> IMAPResult<&[u8], NonEmptyVec<FetchAttributeValue>> {
+pub fn msg_att(input: &[u8]) -> IMAPResult<&[u8], NonEmptyVec<MessageDataItem>> {
     delimited(
         tag(b"("),
         map(
@@ -95,7 +104,7 @@ pub fn msg_att(input: &[u8]) -> IMAPResult<&[u8], NonEmptyVec<FetchAttributeValu
 /// `msg-att-dynamic = "FLAGS" SP "(" [flag-fetch *(SP flag-fetch)] ")"`
 ///
 /// Note: MAY change for a message
-pub fn msg_att_dynamic(input: &[u8]) -> IMAPResult<&[u8], FetchAttributeValue> {
+pub fn msg_att_dynamic(input: &[u8]) -> IMAPResult<&[u8], MessageDataItem> {
     let mut parser = tuple((
         tag_no_case(b"FLAGS"),
         sp,
@@ -104,10 +113,7 @@ pub fn msg_att_dynamic(input: &[u8]) -> IMAPResult<&[u8], FetchAttributeValue> {
 
     let (remaining, (_, _, flags)) = parser(input)?;
 
-    Ok((
-        remaining,
-        FetchAttributeValue::Flags(flags.unwrap_or_default()),
-    ))
+    Ok((remaining, MessageDataItem::Flags(flags.unwrap_or_default())))
 }
 
 /// `msg-att-static = "ENVELOPE" SP envelope /
@@ -119,39 +125,39 @@ pub fn msg_att_dynamic(input: &[u8]) -> IMAPResult<&[u8], FetchAttributeValue> {
 ///                   "UID" SP uniqueid`
 ///
 /// Note: MUST NOT change for a message
-pub fn msg_att_static(input: &[u8]) -> IMAPResult<&[u8], FetchAttributeValue> {
+pub fn msg_att_static(input: &[u8]) -> IMAPResult<&[u8], MessageDataItem> {
     alt((
         map(
             tuple((tag_no_case(b"ENVELOPE"), sp, envelope)),
-            |(_, _, envelope)| FetchAttributeValue::Envelope(envelope),
+            |(_, _, envelope)| MessageDataItem::Envelope(envelope),
         ),
         map(
             tuple((tag_no_case(b"INTERNALDATE"), sp, date_time)),
-            |(_, _, date_time)| FetchAttributeValue::InternalDate(date_time),
+            |(_, _, date_time)| MessageDataItem::InternalDate(date_time),
         ),
         map(
             tuple((tag_no_case(b"RFC822.HEADER"), sp, nstring)),
-            |(_, _, nstring)| FetchAttributeValue::Rfc822Header(nstring),
+            |(_, _, nstring)| MessageDataItem::Rfc822Header(nstring),
         ),
         map(
             tuple((tag_no_case(b"RFC822.TEXT"), sp, nstring)),
-            |(_, _, nstring)| FetchAttributeValue::Rfc822Text(nstring),
+            |(_, _, nstring)| MessageDataItem::Rfc822Text(nstring),
         ),
         map(
             tuple((tag_no_case(b"RFC822.SIZE"), sp, number)),
-            |(_, _, num)| FetchAttributeValue::Rfc822Size(num),
+            |(_, _, num)| MessageDataItem::Rfc822Size(num),
         ),
         map(
             tuple((tag_no_case(b"RFC822"), sp, nstring)),
-            |(_, _, nstring)| FetchAttributeValue::Rfc822(nstring),
+            |(_, _, nstring)| MessageDataItem::Rfc822(nstring),
         ),
         map(
             tuple((tag_no_case(b"BODYSTRUCTURE"), sp, body(8))),
-            |(_, _, body)| FetchAttributeValue::BodyStructure(body),
+            |(_, _, body)| MessageDataItem::BodyStructure(body),
         ),
         map(
             tuple((tag_no_case(b"BODY"), sp, body(8))),
-            |(_, _, body)| FetchAttributeValue::Body(body),
+            |(_, _, body)| MessageDataItem::Body(body),
         ),
         map(
             tuple((
@@ -161,14 +167,14 @@ pub fn msg_att_static(input: &[u8]) -> IMAPResult<&[u8], FetchAttributeValue> {
                 sp,
                 nstring,
             )),
-            |(_, section, origin, _, data)| FetchAttributeValue::BodyExt {
+            |(_, section, origin, _, data)| MessageDataItem::BodyExt {
                 section,
                 origin,
                 data,
             },
         ),
         map(tuple((tag_no_case(b"UID"), sp, uniqueid)), |(_, _, uid)| {
-            FetchAttributeValue::Uid(uid)
+            MessageDataItem::Uid(uid)
         }),
     ))(input)
 }
@@ -193,26 +199,26 @@ mod tests {
     };
 
     #[test]
-    fn test_encode_fetch_attribute() {
+    fn test_encode_message_data_item_name() {
         let tests = [
-            (FetchAttribute::Body, b"BODY".as_ref()),
+            (MessageDataItemName::Body, b"BODY".as_ref()),
             (
-                FetchAttribute::BodyExt {
+                MessageDataItemName::BodyExt {
                     section: None,
                     partial: None,
                     peek: false,
                 },
                 b"BODY[]",
             ),
-            (FetchAttribute::BodyStructure, b"BODYSTRUCTURE"),
-            (FetchAttribute::Envelope, b"ENVELOPE"),
-            (FetchAttribute::Flags, b"FLAGS"),
-            (FetchAttribute::InternalDate, b"INTERNALDATE"),
-            (FetchAttribute::Rfc822, b"RFC822"),
-            (FetchAttribute::Rfc822Header, b"RFC822.HEADER"),
-            (FetchAttribute::Rfc822Size, b"RFC822.SIZE"),
-            (FetchAttribute::Rfc822Text, b"RFC822.TEXT"),
-            (FetchAttribute::Uid, b"UID"),
+            (MessageDataItemName::BodyStructure, b"BODYSTRUCTURE"),
+            (MessageDataItemName::Envelope, b"ENVELOPE"),
+            (MessageDataItemName::Flags, b"FLAGS"),
+            (MessageDataItemName::InternalDate, b"INTERNALDATE"),
+            (MessageDataItemName::Rfc822, b"RFC822"),
+            (MessageDataItemName::Rfc822Header, b"RFC822.HEADER"),
+            (MessageDataItemName::Rfc822Size, b"RFC822.SIZE"),
+            (MessageDataItemName::Rfc822Text, b"RFC822.TEXT"),
+            (MessageDataItemName::Uid, b"UID"),
         ];
 
         for test in tests {
@@ -221,10 +227,10 @@ mod tests {
     }
 
     #[test]
-    fn test_encode_fetch_attribute_value() {
+    fn test_encode_message_data_item() {
         let tests = [
             (
-                FetchAttributeValue::Body(BodyStructure::Single {
+                MessageDataItem::Body(BodyStructure::Single {
                     body: Body {
                         basic: BasicFields {
                             parameter_list: vec![],
@@ -243,7 +249,7 @@ mod tests {
                 b"BODY (\"TEXT\" \"foo\" NIL NIL NIL \"base64\" 42 1337)".as_ref(),
             ),
             (
-                FetchAttributeValue::BodyExt {
+                MessageDataItem::BodyExt {
                     section: None,
                     origin: None,
                     data: NString(None),
@@ -251,7 +257,7 @@ mod tests {
                 b"BODY[] NIL",
             ),
             (
-                FetchAttributeValue::BodyExt {
+                MessageDataItem::BodyExt {
                     section: None,
                     origin: Some(123),
                     data: NString(None),
@@ -259,7 +265,7 @@ mod tests {
                 b"BODY[]<123> NIL",
             ),
             (
-                FetchAttributeValue::BodyStructure(BodyStructure::Single {
+                MessageDataItem::BodyStructure(BodyStructure::Single {
                     body: Body {
                         basic: BasicFields {
                             parameter_list: vec![],
@@ -278,7 +284,7 @@ mod tests {
                 b"BODYSTRUCTURE (\"TEXT\" \"\" NIL NIL NIL \"base64\" 213 224)",
             ),
             (
-                FetchAttributeValue::Envelope(Envelope {
+                MessageDataItem::Envelope(Envelope {
                     date: NString(None),
                     subject: NString(None),
                     from: vec![],
@@ -292,9 +298,9 @@ mod tests {
                 }),
                 b"ENVELOPE (NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL)",
             ),
-            (FetchAttributeValue::Flags(vec![]), b"FLAGS ()"),
+            (MessageDataItem::Flags(vec![]), b"FLAGS ()"),
             (
-                FetchAttributeValue::InternalDate(
+                MessageDataItem::InternalDate(
                     DateTime::try_from(
                         chrono::DateTime::parse_from_rfc2822("Tue, 1 Jul 2003 10:52:37 +0200")
                             .unwrap(),
@@ -303,18 +309,18 @@ mod tests {
                 ),
                 b"INTERNALDATE \"01-Jul-2003 10:52:37 +0200\"",
             ),
-            (FetchAttributeValue::Rfc822(NString(None)), b"RFC822 NIL"),
+            (MessageDataItem::Rfc822(NString(None)), b"RFC822 NIL"),
             (
-                FetchAttributeValue::Rfc822Header(NString(None)),
+                MessageDataItem::Rfc822Header(NString(None)),
                 b"RFC822.HEADER NIL",
             ),
-            (FetchAttributeValue::Rfc822Size(3456), b"RFC822.SIZE 3456"),
+            (MessageDataItem::Rfc822Size(3456), b"RFC822.SIZE 3456"),
             (
-                FetchAttributeValue::Rfc822Text(NString(None)),
+                MessageDataItem::Rfc822Text(NString(None)),
                 b"RFC822.TEXT NIL",
             ),
             (
-                FetchAttributeValue::Uid(NonZeroU32::try_from(u32::MAX).unwrap()),
+                MessageDataItem::Uid(NonZeroU32::try_from(u32::MAX).unwrap()),
                 b"UID 4294967295",
             ),
         ];
diff --git a/src/mailbox.rs b/src/mailbox.rs
index a582b18d..fa7351fd 100644
--- a/src/mailbox.rs
+++ b/src/mailbox.rs
@@ -101,9 +101,9 @@ pub fn mailbox_data(input: &[u8]) -> IMAPResult<&[u8], Data> {
                 sp,
                 delimited(tag(b"("), opt(status_att_list), tag(b")")),
             )),
-            |(_, _, mailbox, _, attributes)| Data::Status {
+            |(_, _, mailbox, _, items)| Data::Status {
                 mailbox,
-                attributes: attributes.unwrap_or_default().into(),
+                items: items.unwrap_or_default().into(),
             },
         ),
         map(
diff --git a/src/response.rs b/src/response.rs
index eef9d6fb..cec3cf54 100644
--- a/src/response.rs
+++ b/src/response.rs
@@ -376,7 +376,7 @@ pub fn message_data(input: &[u8]) -> IMAPResult<&[u8], Data> {
         map(tag_no_case(b"EXPUNGE"), move |_| Data::Expunge(seq)),
         map(
             tuple((tag_no_case(b"FETCH"), sp, msg_att)),
-            move |(_, _, attributes)| Data::Fetch { seq, attributes },
+            move |(_, _, items)| Data::Fetch { seq, items },
         ),
     ))(remaining)
 }
diff --git a/src/status.rs b/src/status.rs
index 09cd655b..5c0a661a 100644
--- a/src/status.rs
+++ b/src/status.rs
@@ -23,23 +23,23 @@ use crate::{
 ///               "UIDNEXT" /
 ///               "UIDVALIDITY" /
 ///               "UNSEEN"`
-pub fn status_att(input: &[u8]) -> IMAPResult<&[u8], StatusAttribute> {
+pub fn status_att(input: &[u8]) -> IMAPResult<&[u8], StatusDataItemName> {
     alt((
-        value(StatusAttribute::Messages, tag_no_case(b"MESSAGES")),
-        value(StatusAttribute::Recent, tag_no_case(b"RECENT")),
-        value(StatusAttribute::UidNext, tag_no_case(b"UIDNEXT")),
-        value(StatusAttribute::UidValidity, tag_no_case(b"UIDVALIDITY")),
-        value(StatusAttribute::Unseen, tag_no_case(b"UNSEEN")),
+        value(StatusDataItemName::Messages, tag_no_case(b"MESSAGES")),
+        value(StatusDataItemName::Recent, tag_no_case(b"RECENT")),
+        value(StatusDataItemName::UidNext, tag_no_case(b"UIDNEXT")),
+        value(StatusDataItemName::UidValidity, tag_no_case(b"UIDVALIDITY")),
+        value(StatusDataItemName::Unseen, tag_no_case(b"UNSEEN")),
         #[cfg(feature = "ext_quota")]
         value(
-            StatusAttribute::DeletedStorage,
+            StatusDataItemName::DeletedStorage,
             tag_no_case(b"DELETED-STORAGE"),
         ),
         #[cfg(feature = "ext_quota")]
-        value(StatusAttribute::Deleted, tag_no_case(b"DELETED")),
+        value(StatusDataItemName::Deleted, tag_no_case(b"DELETED")),
         #[cfg(feature = "ext_condstore_qresync")]
         value(
-            StatusAttribute::HighestModSeq,
+            StatusDataItemName::HighestModSeq,
             tag_no_case(b"HIGHESTMODSEQ"),
         ),
     ))(input)
@@ -48,7 +48,7 @@ pub fn status_att(input: &[u8]) -> IMAPResult<&[u8], StatusAttribute> {
 /// `status-att-list = status-att-val *(SP status-att-val)`
 ///
 /// Note: See errata id: 261
-pub fn status_att_list(input: &[u8]) -> IMAPResult<&[u8], Vec<StatusAttributeValue>> {
+pub fn status_att_list(input: &[u8]) -> IMAPResult<&[u8], Vec<StatusDataItem>> {
     separated_list1(sp, status_att_val)(input)
 }
 
@@ -59,37 +59,37 @@ pub fn status_att_list(input: &[u8]) -> IMAPResult<&[u8], Vec<StatusAttributeVal
 ///                    ("UNSEEN" SP number)`
 ///
 /// Note: See errata id: 261
-fn status_att_val(input: &[u8]) -> IMAPResult<&[u8], StatusAttributeValue> {
+fn status_att_val(input: &[u8]) -> IMAPResult<&[u8], StatusDataItem> {
     alt((
         map(
             tuple((tag_no_case(b"MESSAGES"), sp, number)),
-            |(_, _, num)| StatusAttributeValue::Messages(num),
+            |(_, _, num)| StatusDataItem::Messages(num),
         ),
         map(
             tuple((tag_no_case(b"RECENT"), sp, number)),
-            |(_, _, num)| StatusAttributeValue::Recent(num),
+            |(_, _, num)| StatusDataItem::Recent(num),
         ),
         map(
             tuple((tag_no_case(b"UIDNEXT"), sp, nz_number)),
-            |(_, _, next)| StatusAttributeValue::UidNext(next),
+            |(_, _, next)| StatusDataItem::UidNext(next),
         ),
         map(
             tuple((tag_no_case(b"UIDVALIDITY"), sp, nz_number)),
-            |(_, _, val)| StatusAttributeValue::UidValidity(val),
+            |(_, _, val)| StatusDataItem::UidValidity(val),
         ),
         map(
             tuple((tag_no_case(b"UNSEEN"), sp, number)),
-            |(_, _, num)| StatusAttributeValue::Unseen(num),
+            |(_, _, num)| StatusDataItem::Unseen(num),
         ),
         #[cfg(feature = "ext_quota")]
         map(
             tuple((tag_no_case(b"DELETED-STORAGE"), sp, number64)),
-            |(_, _, num)| StatusAttributeValue::DeletedStorage(num),
+            |(_, _, num)| StatusDataItem::DeletedStorage(num),
         ),
         #[cfg(feature = "ext_quota")]
         map(
             tuple((tag_no_case(b"DELETED"), sp, number)),
-            |(_, _, num)| StatusAttributeValue::Deleted(num),
+            |(_, _, num)| StatusDataItem::Deleted(num),
         ),
     ))(input)
 }
@@ -102,17 +102,17 @@ mod tests {
     use crate::testing::known_answer_test_encode;
 
     #[test]
-    fn test_encode_status_attribute() {
+    fn test_encode_status_data_item_name() {
         let tests = [
-            (StatusAttribute::Messages, b"MESSAGES".as_ref()),
-            (StatusAttribute::Recent, b"RECENT"),
-            (StatusAttribute::UidNext, b"UIDNEXT"),
-            (StatusAttribute::UidValidity, b"UIDVALIDITY"),
-            (StatusAttribute::Unseen, b"UNSEEN"),
+            (StatusDataItemName::Messages, b"MESSAGES".as_ref()),
+            (StatusDataItemName::Recent, b"RECENT"),
+            (StatusDataItemName::UidNext, b"UIDNEXT"),
+            (StatusDataItemName::UidValidity, b"UIDVALIDITY"),
+            (StatusDataItemName::Unseen, b"UNSEEN"),
             #[cfg(feature = "ext_quota")]
-            (StatusAttribute::Deleted, b"DELETED"),
+            (StatusDataItemName::Deleted, b"DELETED"),
             #[cfg(feature = "ext_quota")]
-            (StatusAttribute::DeletedStorage, b"DELETED-STORAGE"),
+            (StatusDataItemName::DeletedStorage, b"DELETED-STORAGE"),
         ];
 
         for test in tests {
@@ -121,24 +121,24 @@ mod tests {
     }
 
     #[test]
-    fn test_encode_status_attribute_value() {
+    fn test_encode_status_data_item() {
         let tests = [
-            (StatusAttributeValue::Messages(0), b"MESSAGES 0".as_ref()),
-            (StatusAttributeValue::Recent(u32::MAX), b"RECENT 4294967295"),
+            (StatusDataItem::Messages(0), b"MESSAGES 0".as_ref()),
+            (StatusDataItem::Recent(u32::MAX), b"RECENT 4294967295"),
             (
-                StatusAttributeValue::UidNext(NonZeroU32::new(1).unwrap()),
+                StatusDataItem::UidNext(NonZeroU32::new(1).unwrap()),
                 b"UIDNEXT 1",
             ),
             (
-                StatusAttributeValue::UidValidity(NonZeroU32::new(u32::MAX).unwrap()),
+                StatusDataItem::UidValidity(NonZeroU32::new(u32::MAX).unwrap()),
                 b"UIDVALIDITY 4294967295",
             ),
-            (StatusAttributeValue::Unseen(0), b"UNSEEN 0"),
+            (StatusDataItem::Unseen(0), b"UNSEEN 0"),
             #[cfg(feature = "ext_quota")]
-            (StatusAttributeValue::Deleted(1), b"DELETED 1"),
+            (StatusDataItem::Deleted(1), b"DELETED 1"),
             #[cfg(feature = "ext_quota")]
             (
-                StatusAttributeValue::DeletedStorage(u64::MAX),
+                StatusDataItem::DeletedStorage(u64::MAX),
                 b"DELETED-STORAGE 18446744073709551615",
             ),
         ];
diff --git a/src/tokio/client.rs b/src/tokio/client.rs
index 1f2a6752..d17b5ecc 100644
--- a/src/tokio/client.rs
+++ b/src/tokio/client.rs
@@ -205,7 +205,7 @@ mod tests {
     use super::*;
     use crate::{
         core::{Literal, NString},
-        fetch::FetchAttributeValue,
+        fetch::MessageDataItem,
         response::{Data, GreetingKind},
         section::Section,
     };
@@ -260,7 +260,7 @@ mod tests {
                 Ok(Some(Event::Response(Response::Data(
                     Data::fetch(
                         12,
-                        vec![FetchAttributeValue::BodyExt {
+                        vec![MessageDataItem::BodyExt {
                             section: Some(Section::Header(None)),
                             origin: None,
                             data: NString(Some(Literal::try_from("abc").unwrap().into())),


Test patch:
diff --git a/tests/trace.rs b/tests/trace.rs
index 8afdfbe5..af4d6cec 100644
--- a/tests/trace.rs
+++ b/tests/trace.rs
@@ -6,7 +6,7 @@ use imap_codec::{
     core::{AString, IString, Literal, NString, Quoted, Tag},
     datetime::DateTime,
     envelope::{Address, Envelope},
-    fetch::{FetchAttribute, FetchAttributeValue, Macro},
+    fetch::{Macro, MessageDataItem, MessageDataItemName},
     flag::{Flag, FlagFetch, FlagPerm, StoreResponse, StoreType},
     response::{Capability, Code, Data, Greeting, Response, Status},
     secret::Secret,
@@ -257,7 +257,7 @@ fn test_from_noop() {
                 Message::Response(Response::Data(
                     Data::fetch(
                         14,
-                        vec![FetchAttributeValue::Flags(vec![
+                        vec![MessageDataItem::Flags(vec![
                             FlagFetch::Flag(Flag::Seen),
                             FlagFetch::Flag(Flag::Deleted),
                         ])],
@@ -955,13 +955,13 @@ fn test_transcript_from_rfc() {
                     Data::fetch(
                         12,
                         vec![
-                            FetchAttributeValue::Flags(vec![FlagFetch::Flag(Flag::Seen)]),
-                            FetchAttributeValue::InternalDate(DateTime::try_from(
+                            MessageDataItem::Flags(vec![FlagFetch::Flag(Flag::Seen)]),
+                            MessageDataItem::InternalDate(DateTime::try_from(
                                 chrono::DateTime::parse_from_rfc3339("1996-07-17T02:44:25-07:00")
                                     .unwrap(),
                             ).unwrap()),
-                            FetchAttributeValue::Rfc822Size(4286),
-                            FetchAttributeValue::Envelope(Envelope {
+                            MessageDataItem::Rfc822Size(4286),
+                            MessageDataItem::Envelope(Envelope {
                                 date: NString::from(
                                     Quoted::try_from("Wed, 17 Jul 1996 02:23:25 -0700 (PDT)")
                                         .unwrap(),
@@ -1031,7 +1031,7 @@ fn test_transcript_from_rfc() {
                                         .unwrap(),
                                 ),
                             }),
-                            FetchAttributeValue::Body(BodyStructure::Single {
+                            MessageDataItem::Body(BodyStructure::Single {
                                 body: Body {
                                     basic: BasicFields {
                                         parameter_list: vec![(
@@ -1075,7 +1075,7 @@ fn test_transcript_from_rfc() {
                         "a004",
                         CommandBody::fetch(
                             "12",
-                            vec![FetchAttribute::BodyExt {
+                            vec![MessageDataItemName::BodyExt {
                                 section: Some(Section::Header(None)),
                                 peek: false,
                                 partial: None,
@@ -1102,7 +1102,7 @@ Content-Type: TEXT/PLAIN; CHARSET=US-ASCII\r
                 Message::Response(Response::Data(
                     Data::fetch(
                         12,
-                        vec![FetchAttributeValue::BodyExt {
+                        vec![MessageDataItem::BodyExt {
                             section: Some(Section::Header(None)),
                             origin: None,
                             data: NString::from(
@@ -1159,7 +1159,7 @@ Content-Type: TEXT/PLAIN; CHARSET=US-ASCII\r
                 Message::Response(Response::Data(
                     Data::fetch(
                         12,
-                        vec![FetchAttributeValue::Flags(vec![
+                        vec![MessageDataItem::Flags(vec![
                             FlagFetch::Flag(Flag::Seen),
                             FlagFetch::Flag(Flag::Deleted),
                         ])],