compose_lens/model/
ulimit.rs1use super::{FieldReference, Located};
4use crate::source::SourceSpan;
5
6#[derive(Debug, Clone, PartialEq, Eq)]
8pub struct Ulimits {
9 span: SourceSpan,
10 entries: Vec<Ulimit>,
11}
12
13impl Ulimits {
14 pub(super) const fn new(span: SourceSpan, entries: Vec<Ulimit>) -> Self {
15 Self { span, entries }
16 }
17
18 #[must_use]
20 pub const fn span(&self) -> SourceSpan {
21 self.span
22 }
23
24 #[must_use]
26 pub fn entries(&self) -> &[Ulimit] {
27 &self.entries
28 }
29}
30
31#[derive(Debug, Clone, PartialEq, Eq)]
33pub struct Ulimit {
34 name: Located<String>,
35 span: SourceSpan,
36 value: UlimitValue,
37}
38
39impl Ulimit {
40 pub(super) const fn new(name: Located<String>, span: SourceSpan, value: UlimitValue) -> Self {
41 Self { name, span, value }
42 }
43
44 #[must_use]
46 pub const fn name(&self) -> &Located<String> {
47 &self.name
48 }
49
50 #[must_use]
52 pub const fn span(&self) -> SourceSpan {
53 self.span
54 }
55
56 #[must_use]
58 pub const fn value(&self) -> &UlimitValue {
59 &self.value
60 }
61}
62
63#[derive(Debug, Clone, PartialEq, Eq)]
65pub enum UlimitValue {
66 Single(Located<LimitValue>),
68 Range(UlimitRange),
70}
71
72#[derive(Debug, Clone, PartialEq, Eq)]
74pub enum LimitValue {
75 Unlimited,
77 Number(String),
79 Expression(String),
81 Other(String),
83}
84
85impl LimitValue {
86 pub(crate) fn parse(value: String) -> Self {
87 if value == "-1" {
88 Self::Unlimited
89 } else if value.bytes().all(|byte| byte.is_ascii_digit()) && !value.is_empty() {
90 Self::Number(value)
91 } else if value.contains('$') {
92 Self::Expression(value)
93 } else {
94 Self::Other(value)
95 }
96 }
97
98 #[must_use]
100 pub const fn is_valid(&self) -> bool {
101 !matches!(self, Self::Other(_))
102 }
103
104 #[must_use]
106 pub fn raw(&self) -> &str {
107 match self {
108 Self::Unlimited => "-1",
109 Self::Number(value) | Self::Expression(value) | Self::Other(value) => value,
110 }
111 }
112}
113
114pub(crate) fn valid_ulimit_name(name: &str) -> bool {
115 !name.is_empty() && name.bytes().all(|byte| byte.is_ascii_lowercase())
116}
117
118#[derive(Debug, Clone, PartialEq, Eq)]
120pub struct UlimitRange {
121 span: SourceSpan,
122 soft: Option<Located<LimitValue>>,
123 hard: Option<Located<LimitValue>>,
124 extension_fields: Vec<FieldReference>,
125 unknown_fields: Vec<FieldReference>,
126}
127
128impl UlimitRange {
129 pub(super) const fn new(span: SourceSpan) -> Self {
130 Self {
131 span,
132 soft: None,
133 hard: None,
134 extension_fields: Vec::new(),
135 unknown_fields: Vec::new(),
136 }
137 }
138
139 pub(super) fn set_soft(&mut self, value: Located<LimitValue>) {
140 self.soft = Some(value);
141 }
142
143 pub(super) fn set_hard(&mut self, value: Located<LimitValue>) {
144 self.hard = Some(value);
145 }
146
147 pub(super) fn push_extension(&mut self, field: FieldReference) {
148 self.extension_fields.push(field);
149 }
150
151 pub(super) fn push_unknown(&mut self, field: FieldReference) {
152 self.unknown_fields.push(field);
153 }
154
155 #[must_use]
157 pub const fn span(&self) -> SourceSpan {
158 self.span
159 }
160
161 #[must_use]
163 pub const fn soft(&self) -> Option<&Located<LimitValue>> {
164 self.soft.as_ref()
165 }
166
167 #[must_use]
169 pub const fn hard(&self) -> Option<&Located<LimitValue>> {
170 self.hard.as_ref()
171 }
172
173 #[must_use]
175 pub fn extension_fields(&self) -> &[FieldReference] {
176 &self.extension_fields
177 }
178
179 #[must_use]
181 pub fn unknown_fields(&self) -> &[FieldReference] {
182 &self.unknown_fields
183 }
184}