     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88

    // Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT
    // file at the top-level directory of this distribution and at
    // http://rust-lang.org/COPYRIGHT.
    //
    // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
    // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
    // option. This file may not be copied, modified, or distributed
    // except according to those terms.

    use re_trait::{RegularExpression, Slot};

    /// Plugin is the compiler plugin's data structure. It declare some static
    /// data (like capture groups and the original regex string), but defines its
    /// matching engine as a simple function.
    #[doc(hidden)]
    pub struct Plugin {
        #[doc(hidden)]
        pub original: &'static str,
        #[doc(hidden)]
        pub names: &'static &'static [Option<&'static str>],
        #[doc(hidden)]
        pub groups: &'static &'static [(&'static str, usize)],
        #[doc(hidden)]
        pub prog: fn(&mut [Slot], &str, usize) -> bool,
    }

    impl Copy for Plugin {}

    impl Clone for Plugin {
        fn clone(&self) -> Plugin {
            *self
        }
    }

    impl RegularExpression for Plugin {
        type Text = str;

        fn slots_len(&self) -> usize {
            self.names.len() * 2
        }

        fn next_after_empty(&self, text: &str, i: usize) -> usize {
            let b = match text.as_bytes().get(i) {
                None => return text.len() + 1,
                Some(&b) => b,
            };
            let inc = if b <= 0x7F {
                1
            } else if b <= 0b110_11111 {
                2
            } else if b <= 0b1110_1111 {
                3
            } else {
                4
            };
            i + inc
        }

        fn shortest_match_at(&self, text: &str, start: usize) -> Option<usize> {
            self.find_at(text, start).map(|(_, e)| e)
        }

        fn is_match_at(&self, text: &str, start: usize) -> bool {
            (self.prog)(&mut [], text, start)
        }

        fn find_at(&self, text: &str, start: usize) -> Option<(usize, usize)> {
            let mut slots = [None, None];
            self.read_captures_at(&mut slots, text, start)
        }

        fn read_captures_at<'t>(
            &self,
            slots: &mut [Slot],
            text: &'t str,
            start: usize,
        ) -> Option<(usize, usize)> {
            for slot in slots.iter_mut() {
                *slot = None;
            }
            (self.prog)(slots, text, start);
            match (slots[0], slots[1]) {
                (Some(s), Some(e)) => Some((s, e)),
                _ => None,
            }
        }
    }

# Help

## Keyboard Shortcuts

?
  Show this help dialog
S
  Focus the search field
⇤
  Move up in search results
⇥
  Move down in search results
⏎
  Go to active search result

## Search Tricks

Prefix searches with a type followed by a colon (e.g. `fn:`) to restrict the search to a given type.

Accepted types are: `fn`, `mod`, `struct`, `enum`, `trait`, `type`, `macro`, and `const`.

Search functions by type signature (e.g. `vec -> usize` or `* -> vec`)