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
use std::cmp::Ordering;
use crate::convert::{FromMrb, RustBackedValue};
use crate::extn::core::matchdata::MatchData;
use crate::value::Value;
use crate::Mrb;
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
pub enum Error {
Fatal,
}
pub fn method(interp: &Mrb, value: &Value) -> Result<Value, Error> {
let data = unsafe { MatchData::try_from_ruby(interp, value) }.map_err(|_| Error::Fatal)?;
let borrow = data.borrow();
let regex = (*borrow.regexp.regex).as_ref().ok_or(Error::Fatal)?;
let mut names = vec![];
let mut capture_names = regex.capture_names().collect::<Vec<_>>();
capture_names.sort_by(|a, b| {
a.1.iter()
.fold(u32::max_value(), |a, &b| a.min(b))
.partial_cmp(b.1.iter().fold(&u32::max_value(), |a, b| a.min(b)))
.unwrap_or(Ordering::Equal)
});
for (name, _) in capture_names {
if !names.contains(&name) {
names.push(name);
}
}
Ok(Value::from_mrb(interp, names))
}