use super::{FieldReference, Located};
use crate::source::SourceSpan;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Ulimits {
span: SourceSpan,
entries: Vec<Ulimit>,
}
impl Ulimits {
pub(super) const fn new(span: SourceSpan, entries: Vec<Ulimit>) -> Self {
Self { span, entries }
}
#[must_use]
pub const fn span(&self) -> SourceSpan {
self.span
}
#[must_use]
pub fn entries(&self) -> &[Ulimit] {
&self.entries
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Ulimit {
name: Located<String>,
span: SourceSpan,
value: UlimitValue,
}
impl Ulimit {
pub(super) const fn new(name: Located<String>, span: SourceSpan, value: UlimitValue) -> Self {
Self { name, span, value }
}
#[must_use]
pub const fn name(&self) -> &Located<String> {
&self.name
}
#[must_use]
pub const fn span(&self) -> SourceSpan {
self.span
}
#[must_use]
pub const fn value(&self) -> &UlimitValue {
&self.value
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum UlimitValue {
Single(Located<LimitValue>),
Range(UlimitRange),
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum LimitValue {
Unlimited,
Number(String),
Expression(String),
Other(String),
}
impl LimitValue {
pub(super) fn parse(value: String) -> Self {
if value == "-1" {
Self::Unlimited
} else if value.bytes().all(|byte| byte.is_ascii_digit()) && !value.is_empty() {
Self::Number(value)
} else if value.contains('$') {
Self::Expression(value)
} else {
Self::Other(value)
}
}
#[must_use]
pub const fn is_valid(&self) -> bool {
!matches!(self, Self::Other(_))
}
#[must_use]
pub fn raw(&self) -> &str {
match self {
Self::Unlimited => "-1",
Self::Number(value) | Self::Expression(value) | Self::Other(value) => value,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct UlimitRange {
span: SourceSpan,
soft: Option<Located<LimitValue>>,
hard: Option<Located<LimitValue>>,
extension_fields: Vec<FieldReference>,
unknown_fields: Vec<FieldReference>,
}
impl UlimitRange {
pub(super) const fn new(span: SourceSpan) -> Self {
Self {
span,
soft: None,
hard: None,
extension_fields: Vec::new(),
unknown_fields: Vec::new(),
}
}
pub(super) fn set_soft(&mut self, value: Located<LimitValue>) {
self.soft = Some(value);
}
pub(super) fn set_hard(&mut self, value: Located<LimitValue>) {
self.hard = Some(value);
}
pub(super) fn push_extension(&mut self, field: FieldReference) {
self.extension_fields.push(field);
}
pub(super) fn push_unknown(&mut self, field: FieldReference) {
self.unknown_fields.push(field);
}
#[must_use]
pub const fn span(&self) -> SourceSpan {
self.span
}
#[must_use]
pub const fn soft(&self) -> Option<&Located<LimitValue>> {
self.soft.as_ref()
}
#[must_use]
pub const fn hard(&self) -> Option<&Located<LimitValue>> {
self.hard.as_ref()
}
#[must_use]
pub fn extension_fields(&self) -> &[FieldReference] {
&self.extension_fields
}
#[must_use]
pub fn unknown_fields(&self) -> &[FieldReference] {
&self.unknown_fields
}
}