xml5ever/tokenizer/
qname.rs

1// Copyright 2014-2017 The html5ever Project Developers. See the
2// COPYRIGHT file at the top-level directory of this distribution.
3//
4// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
5// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
7// option. This file may not be copied, modified, or distributed
8// except according to those terms.
9
10enum QualNameState {
11    BeforeName,
12    InName,
13    AfterColon,
14}
15
16pub struct QualNameTokenizer<'a> {
17    state: QualNameState,
18    slice: &'a [u8],
19    valid_index: Option<u32>,
20    curr_ind: usize,
21}
22
23impl QualNameTokenizer<'_> {
24    pub fn new(tag: &[u8]) -> QualNameTokenizer<'_> {
25        QualNameTokenizer {
26            state: QualNameState::BeforeName,
27            slice: tag,
28            valid_index: None,
29            curr_ind: 0,
30        }
31    }
32
33    pub fn run(&mut self) -> Option<u32> {
34        if !self.slice.is_empty() {
35            loop {
36                if !self.step() {
37                    break;
38                }
39            }
40        }
41        self.valid_index
42    }
43
44    fn incr(&mut self) -> bool {
45        if self.curr_ind + 1 < self.slice.len() {
46            self.curr_ind += 1;
47            return true;
48        }
49        false
50    }
51
52    fn step(&mut self) -> bool {
53        match self.state {
54            QualNameState::BeforeName => self.do_before_name(),
55            QualNameState::InName => self.do_in_name(),
56            QualNameState::AfterColon => self.do_after_colon(),
57        }
58    }
59
60    fn do_before_name(&mut self) -> bool {
61        if self.slice[self.curr_ind] == b':' {
62            false
63        } else {
64            self.state = QualNameState::InName;
65            self.incr()
66        }
67    }
68
69    fn do_in_name(&mut self) -> bool {
70        if self.slice[self.curr_ind] == b':' && self.curr_ind + 1 < self.slice.len() {
71            self.valid_index = Some(self.curr_ind as u32);
72            self.state = QualNameState::AfterColon;
73        }
74        self.incr()
75    }
76
77    fn do_after_colon(&mut self) -> bool {
78        if self.slice[self.curr_ind] == b':' {
79            self.valid_index = None;
80            return false;
81        }
82        self.incr()
83    }
84}