Check if a name is valid kebab-case
(name: &str)
| 103 | impl DefaultSkillValidator { |
| 104 | /// Check if a name is valid kebab-case |
| 105 | fn is_kebab_case(name: &str) -> bool { |
| 106 | if name.is_empty() { |
| 107 | return false; |
| 108 | } |
| 109 | // Must start and end with alphanumeric |
| 110 | let bytes = name.as_bytes(); |
| 111 | if !bytes[0].is_ascii_alphanumeric() || !bytes[bytes.len() - 1].is_ascii_alphanumeric() { |
| 112 | return false; |
| 113 | } |
| 114 | // Only lowercase alphanumeric and hyphens, no consecutive hyphens |
| 115 | let mut prev_hyphen = false; |
| 116 | for &b in bytes { |
| 117 | if b == b'-' { |
| 118 | if prev_hyphen { |
| 119 | return false; |
| 120 | } |
| 121 | prev_hyphen = true; |
| 122 | } else if b.is_ascii_lowercase() || b.is_ascii_digit() { |
| 123 | prev_hyphen = false; |
| 124 | } else { |
| 125 | return false; |
| 126 | } |
| 127 | } |
| 128 | true |
| 129 | } |
| 130 | } |
| 131 | |
| 132 | impl SkillValidator for DefaultSkillValidator { |