pub const MAX_LINE_LENGTH: usize = 2048;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum LineType {
Directive { command: String, args: String },
Comment(String),
Blank,
}
pub fn normalize_line(line: &str) -> LineType {
let trimmed = line.trim_start();
if trimmed.is_empty() {
return LineType::Blank;
}
if let Some(first) = trimmed.chars().next()
&& matches!(first, '!' | ';' | '#' | '%')
{
let comment = trimmed[1..].trim();
return LineType::Comment(comment.to_string());
}
let mut result = String::with_capacity(line.len());
let mut in_space = false;
let mut first = true;
for ch in line.chars() {
if ch.is_ascii_whitespace() {
if !first {
in_space = true;
}
} else {
if in_space {
result.push(' ');
in_space = false;
}
result.push(ch);
first = false;
}
}
if let Some(space_pos) = result.find(' ') {
let command = result[..space_pos].to_string();
let args = result[space_pos + 1..].to_string();
LineType::Directive { command, args }
} else {
LineType::Directive {
command: result,
args: String::new(),
}
}
}
pub fn split_word(input: &str) -> (&str, &str) {
let trimmed = input.trim_start();
if trimmed.is_empty() {
return ("", "");
}
match trimmed.find(char::is_whitespace) {
Some(space) => (&trimmed[..space], trimmed[space..].trim_start()),
None => (trimmed, ""),
}
}
pub fn count_args(args: &str) -> usize {
if args.is_empty() {
return 0;
}
args.split(' ').count()
}