Fixed codepoint width of a node, None when it varies. */
(node: &Node)
| 295 | |
| 296 | /* Fixed codepoint width of a node, None when it varies. */ |
| 297 | pub fn fixed_len(node: &Node) -> Option<usize> { |
| 298 | match node { |
| 299 | Node::Empty | Node::Start | Node::End | Node::WordBoundary | Node::NotWordBoundary => Some(0), |
| 300 | Node::Look { .. } => Some(0), |
| 301 | Node::Char(_) | Node::AnyChar | Node::Class { .. } => Some(1), |
| 302 | Node::Concat(v) => { |
| 303 | let mut total = 0; |
| 304 | for n in v { total += fixed_len(n)?; } |
| 305 | Some(total) |
| 306 | } |
| 307 | Node::Alt(v) => { |
| 308 | let mut it = v.iter(); |
| 309 | let first = fixed_len(it.next()?)?; |
| 310 | for n in it { if fixed_len(n)? != first { return None; } } |
| 311 | Some(first) |
| 312 | } |
| 313 | Node::Group { node, .. } | Node::NonCap(node) => fixed_len(node), |
| 314 | Node::Repeat { node, min, max, .. } => { |
| 315 | let m = (*max)?; |
| 316 | if m != *min { return None; } |
| 317 | Some(fixed_len(node)? * m) |
| 318 | } |
| 319 | Node::Backref(_) => None, |
| 320 | } |
| 321 | } |