use super::{
section_name::SectionName, section_type::SectionType, whitespace::Whitespace, SectionPath,
};
use crate::lexer::{Parsable, ParserOutput};
use nom::{
branch::alt,
bytes::complete::tag,
combinator::map,
sequence::{delimited, separated_pair},
};
use std::fmt::Display;
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Default, Hash)]
pub struct ConfigHeader {
pub(crate) section_name: Option<SectionName>,
pub(crate) section_type: SectionType,
pub(crate) whitespace: Whitespace,
}
impl ConfigHeader {
pub fn new(section_type: SectionType, section_name: Option<SectionName>) -> Self {
Self {
section_name,
section_type,
whitespace: Default::default(),
}
}
pub fn is_default_profile(&self) -> bool {
self.section_name
.as_ref()
.map(|inner| *inner == *"default")
.unwrap_or_default()
&& self.section_type == SectionType::Profile
}
}
impl From<SectionPath> for ConfigHeader {
fn from(value: SectionPath) -> Self {
Self::new(value.section_type, value.section_name)
}
}
impl Display for ConfigHeader {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
if let Some(section_name) = &self.section_name {
if self.is_default_profile() {
write!(f, "[{}]{}", section_name, self.whitespace)
} else {
write!(
f,
"[{} {}]{}",
self.section_type, section_name, self.whitespace
)
}
} else {
write!(f, "[{}]{}", self.section_type, self.whitespace)
}
}
}
impl<'a> Parsable<'a> for ConfigHeader {
type Output = Self;
fn parse(input: &'a str) -> ParserOutput<'a, Self::Output> {
let (next, (section_name, section_type)) = delimited(
tag("["),
alt((
map(tag("default"), |default: &str| {
(Some(SectionName(default.to_string())), SectionType::Profile)
}),
map(
separated_pair(SectionType::parse, tag(" "), SectionName::parse),
|(section_type, section_name)| (Some(section_name), section_type),
),
map(SectionType::parse, |section_type| (None, section_type)),
)),
tag("]"),
)(input)?;
let (next, whitespace) = Whitespace::parse(next)?;
let header = Self {
section_name,
section_type,
whitespace,
};
Ok((next, header))
}
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Default, Hash)]
pub struct CredentialHeader {
pub(crate) profile_name: SectionName,
pub(crate) whitespace: Whitespace,
}
impl CredentialHeader {
pub fn new(profile_name: SectionName) -> Self {
Self {
profile_name,
whitespace: Whitespace::default(),
}
}
pub fn get_type(&self) -> &SectionType {
&SectionType::Profile
}
pub fn get_name(&self) -> &SectionName {
&self.profile_name
}
}
impl Display for CredentialHeader {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "[{}]", self.profile_name)
}
}
impl<'a> Parsable<'a> for CredentialHeader {
type Output = Self;
fn parse(input: &'a str) -> ParserOutput<'a, Self::Output> {
let (next, profile_name) = delimited(tag("["), SectionName::parse, tag("]"))(input)?;
let (next, whitespace) = Whitespace::parse(next)?;
let header = Self {
profile_name,
whitespace,
};
Ok((next, header))
}
}