| 2969 | } |
| 2970 | |
| 2971 | fn regexp_matches<'a>( |
| 2972 | exprs: &[Datum<'a>], |
| 2973 | ) -> Result<impl Iterator<Item = (Row, Diff)> + 'a, EvalError> { |
| 2974 | // There are only two acceptable ways to call this function: |
| 2975 | // 1. regexp_matches(string, regex) |
| 2976 | // 2. regexp_matches(string, regex, flag) |
| 2977 | assert!(exprs.len() == 2 || exprs.len() == 3); |
| 2978 | let a = exprs[0].unwrap_str(); |
| 2979 | let r = exprs[1].unwrap_str(); |
| 2980 | |
| 2981 | let (regex, opts) = if exprs.len() == 3 { |
| 2982 | let flag = exprs[2].unwrap_str(); |
| 2983 | let opts = AnalyzedRegexOpts::from_str(flag)?; |
| 2984 | (AnalyzedRegex::new(r, opts)?, opts) |
| 2985 | } else { |
| 2986 | let opts = AnalyzedRegexOpts::default(); |
| 2987 | (AnalyzedRegex::new(r, opts)?, opts) |
| 2988 | }; |
| 2989 | |
| 2990 | let regex = regex.inner().clone(); |
| 2991 | |
| 2992 | let iter = regex.captures_iter(a).map(move |captures| { |
| 2993 | let matches = captures |
| 2994 | .iter() |
| 2995 | // The first match is the *entire* match, we want the capture groups by themselves. |
| 2996 | .skip(1) |
| 2997 | .map(|m| Datum::from(m.map(|m| m.as_str()))) |
| 2998 | .collect::<Vec<_>>(); |
| 2999 | |
| 3000 | let mut binding = SharedRow::get(); |
| 3001 | let mut packer = binding.packer(); |
| 3002 | |
| 3003 | let dimension = ArrayDimension { |
| 3004 | lower_bound: 1, |
| 3005 | length: matches.len(), |
| 3006 | }; |
| 3007 | packer |
| 3008 | .try_push_array(&[dimension], matches) |
| 3009 | .expect("generated dimensions above"); |
| 3010 | |
| 3011 | (binding.clone(), Diff::ONE) |
| 3012 | }); |
| 3013 | |
| 3014 | // This is slightly unfortunate, but we need to collect the captures into a |
| 3015 | // Vec before we can yield them, because we can't return a iter with a |
| 3016 | // reference to the local `regex` variable. |
| 3017 | // We attempt to minimize the cost of this by using a SmallVec. |
| 3018 | let out = iter.collect::<SmallVec<[_; 3]>>(); |
| 3019 | |
| 3020 | if opts.global { |
| 3021 | Ok(Either::Left(out.into_iter())) |
| 3022 | } else { |
| 3023 | Ok(Either::Right(out.into_iter().take(1))) |
| 3024 | } |
| 3025 | } |
| 3026 | |
| 3027 | fn generate_series<N>( |
| 3028 | start: N, |