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