use crate::v2_model::V2Ref;
pub fn parse_v2_ref(s: &str) -> Option<V2Ref> {
if !s.starts_with('@') {
return None;
}
let rest = &s[1..];
if let Some(path) = rest.strip_prefix("input.") {
if path.is_empty() {
return None;
}
return Some(V2Ref::Input(path.to_string()));
}
if let Some(path) = rest.strip_prefix("context.") {
if path.is_empty() {
return None;
}
return Some(V2Ref::Context(path.to_string()));
}
if let Some(path) = rest.strip_prefix("out.") {
if path.is_empty() {
return None;
}
return Some(V2Ref::Out(path.to_string()));
}
if rest == "input" {
return Some(V2Ref::Input(String::new()));
}
if rest == "context" {
return Some(V2Ref::Context(String::new()));
}
if rest == "out" {
return Some(V2Ref::Out(String::new()));
}
if let Some(path) = rest.strip_prefix("item.") {
if path.is_empty() {
return None;
}
return Some(V2Ref::Item(path.to_string()));
}
if let Some(path) = rest.strip_prefix("item") {
if path.is_empty() {
return Some(V2Ref::Item(String::new()));
}
}
if let Some(path) = rest.strip_prefix("acc.") {
if path.is_empty() {
return None;
}
return Some(V2Ref::Acc(path.to_string()));
}
if let Some(path) = rest.strip_prefix("acc") {
if path.is_empty() {
return Some(V2Ref::Acc(String::new()));
}
}
if is_valid_identifier(rest) {
return Some(V2Ref::Local(rest.to_string()));
}
None
}
fn is_valid_identifier(s: &str) -> bool {
if s.is_empty() {
return false;
}
let mut chars = s.chars();
match chars.next() {
Some(c) if c.is_ascii_alphabetic() || c == '_' => {}
_ => return false,
}
chars.all(|c| c.is_ascii_alphanumeric() || c == '_')
}
pub fn is_pipe_value(s: &str) -> bool {
s == "$"
}
pub fn is_literal_escape(s: &str) -> bool {
s.starts_with("lit:")
}
pub fn extract_literal(s: &str) -> Option<&str> {
s.strip_prefix("lit:")
}
pub fn is_v2_ref(s: &str) -> bool {
s.starts_with('@')
}