noodles_sam/header/record/value/map/
builder.rs

1//! SAM header record map value builder.
2
3use std::{error, fmt};
4
5use bstr::BString;
6
7use super::{tag, Map, OtherFields};
8
9/// An error returned when a SAM header record map value fails to build.
10#[derive(Clone, Debug, Eq, PartialEq)]
11pub enum BuildError {
12    /// A required field is missing.
13    MissingField(&'static str),
14    /// A value is invalid.
15    InvalidValue(&'static str),
16}
17
18impl error::Error for BuildError {}
19
20impl fmt::Display for BuildError {
21    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
22        match self {
23            Self::MissingField(tag) => write!(f, "missing field: {tag}"),
24            Self::InvalidValue(tag) => write!(f, "invalid value: {tag}"),
25        }
26    }
27}
28
29/// An inner SAM header map value builder.
30pub trait Inner<I>: Default
31where
32    I: super::Inner,
33{
34    /// Builds the SAM header map value.
35    fn build(self) -> Result<I, BuildError>;
36}
37
38/// A SAM header record map value builder.
39pub struct Builder<I>
40where
41    I: super::Inner,
42{
43    pub(crate) inner: I::Builder,
44    other_fields: OtherFields<I::StandardTag>,
45}
46
47impl<I> Builder<I>
48where
49    I: super::Inner,
50{
51    /// Inserts a key-value pair into the other fields.
52    ///
53    /// # Examples
54    ///
55    /// ```
56    /// use bstr::BString;
57    /// use noodles_sam::header::record::value::{map::{Header, Tag}, Map};
58    ///
59    /// let nd = match Tag::try_from([b'n', b'd']) {
60    ///     Ok(Tag::Other(tag)) => tag,
61    ///     _ => unreachable!(),
62    /// };
63    ///
64    /// let header = Map::<Header>::builder().insert(nd, "noodles").build()?;
65    ///
66    /// assert_eq!(header.other_fields().get(b"nd"), Some(&BString::from("noodles")));
67    /// # Ok::<_, noodles_sam::header::record::value::map::builder::BuildError>(())
68    /// ```
69    pub fn insert<V>(mut self, key: tag::Other<I::StandardTag>, value: V) -> Self
70    where
71        V: Into<BString>,
72    {
73        self.other_fields.insert(key, value.into());
74        self
75    }
76
77    /// Builds a SAM header record map value.
78    ///
79    /// # Examples
80    ///
81    /// ```
82    /// use noodles_sam::header::record::value::{map::Header, Map};
83    /// let header = Map::<Header>::builder().build()?;
84    /// # Ok::<_, noodles_sam::header::record::value::map::builder::BuildError>(())
85    pub fn build(self) -> Result<Map<I>, BuildError> {
86        let inner = self.inner.build()?;
87
88        Ok(Map {
89            inner,
90            other_fields: self.other_fields,
91        })
92    }
93}
94
95impl<I> Default for Builder<I>
96where
97    I: super::Inner,
98{
99    fn default() -> Self {
100        Self {
101            inner: I::Builder::default(),
102            other_fields: OtherFields::new(),
103        }
104    }
105}