1cdb3e2c8Sopenharmony_ci//! Iterators provided by this crate. 2cdb3e2c8Sopenharmony_ci 3cdb3e2c8Sopenharmony_ci#![cfg_attr(os_str_bytes_docs_rs, doc(cfg(feature = "raw_os_str")))] 4cdb3e2c8Sopenharmony_ci 5cdb3e2c8Sopenharmony_ciuse std::convert; 6cdb3e2c8Sopenharmony_ciuse std::fmt; 7cdb3e2c8Sopenharmony_ciuse std::fmt::Debug; 8cdb3e2c8Sopenharmony_ciuse std::fmt::Formatter; 9cdb3e2c8Sopenharmony_ciuse std::iter::FusedIterator; 10cdb3e2c8Sopenharmony_ci 11cdb3e2c8Sopenharmony_ciuse super::pattern::Encoded; 12cdb3e2c8Sopenharmony_ciuse super::Pattern; 13cdb3e2c8Sopenharmony_ciuse super::RawOsStr; 14cdb3e2c8Sopenharmony_ci 15cdb3e2c8Sopenharmony_ci// [memchr::memmem::FindIter] is not currently used, since this struct would 16cdb3e2c8Sopenharmony_ci// become self-referential. Additionally, that iterator does not implement 17cdb3e2c8Sopenharmony_ci// [DoubleEndedIterator], and its implementation would likely require 18cdb3e2c8Sopenharmony_ci// significant changes to implement that trait. 19cdb3e2c8Sopenharmony_ci/// The iterator returned by [`RawOsStr::split`]. 20cdb3e2c8Sopenharmony_cipub struct Split<'a, P> 21cdb3e2c8Sopenharmony_ciwhere 22cdb3e2c8Sopenharmony_ci P: Pattern, 23cdb3e2c8Sopenharmony_ci{ 24cdb3e2c8Sopenharmony_ci string: Option<&'a RawOsStr>, 25cdb3e2c8Sopenharmony_ci pat: P::__Encoded, 26cdb3e2c8Sopenharmony_ci} 27cdb3e2c8Sopenharmony_ci 28cdb3e2c8Sopenharmony_ciimpl<'a, P> Split<'a, P> 29cdb3e2c8Sopenharmony_ciwhere 30cdb3e2c8Sopenharmony_ci P: Pattern, 31cdb3e2c8Sopenharmony_ci{ 32cdb3e2c8Sopenharmony_ci #[track_caller] 33cdb3e2c8Sopenharmony_ci pub(super) fn new(string: &'a RawOsStr, pat: P) -> Self { 34cdb3e2c8Sopenharmony_ci let pat = pat.__encode(); 35cdb3e2c8Sopenharmony_ci assert!( 36cdb3e2c8Sopenharmony_ci !pat.__get().is_empty(), 37cdb3e2c8Sopenharmony_ci "cannot split using an empty pattern", 38cdb3e2c8Sopenharmony_ci ); 39cdb3e2c8Sopenharmony_ci Self { 40cdb3e2c8Sopenharmony_ci string: Some(string), 41cdb3e2c8Sopenharmony_ci pat, 42cdb3e2c8Sopenharmony_ci } 43cdb3e2c8Sopenharmony_ci } 44cdb3e2c8Sopenharmony_ci} 45cdb3e2c8Sopenharmony_ci 46cdb3e2c8Sopenharmony_cimacro_rules! impl_next { 47cdb3e2c8Sopenharmony_ci ( $self:ident , $split_method:ident , $swap_fn:expr ) => {{ 48cdb3e2c8Sopenharmony_ci $self 49cdb3e2c8Sopenharmony_ci .string? 50cdb3e2c8Sopenharmony_ci .$split_method(&$self.pat) 51cdb3e2c8Sopenharmony_ci .map(|substrings| { 52cdb3e2c8Sopenharmony_ci let (substring, string) = $swap_fn(substrings); 53cdb3e2c8Sopenharmony_ci $self.string = Some(string); 54cdb3e2c8Sopenharmony_ci substring 55cdb3e2c8Sopenharmony_ci }) 56cdb3e2c8Sopenharmony_ci .or_else(|| $self.string.take()) 57cdb3e2c8Sopenharmony_ci }}; 58cdb3e2c8Sopenharmony_ci} 59cdb3e2c8Sopenharmony_ci 60cdb3e2c8Sopenharmony_ciimpl<P> Clone for Split<'_, P> 61cdb3e2c8Sopenharmony_ciwhere 62cdb3e2c8Sopenharmony_ci P: Pattern, 63cdb3e2c8Sopenharmony_ci{ 64cdb3e2c8Sopenharmony_ci #[inline] 65cdb3e2c8Sopenharmony_ci fn clone(&self) -> Self { 66cdb3e2c8Sopenharmony_ci Self { 67cdb3e2c8Sopenharmony_ci string: self.string, 68cdb3e2c8Sopenharmony_ci pat: self.pat.clone(), 69cdb3e2c8Sopenharmony_ci } 70cdb3e2c8Sopenharmony_ci } 71cdb3e2c8Sopenharmony_ci} 72cdb3e2c8Sopenharmony_ci 73cdb3e2c8Sopenharmony_ciimpl<P> Debug for Split<'_, P> 74cdb3e2c8Sopenharmony_ciwhere 75cdb3e2c8Sopenharmony_ci P: Pattern, 76cdb3e2c8Sopenharmony_ci{ 77cdb3e2c8Sopenharmony_ci #[inline] 78cdb3e2c8Sopenharmony_ci fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { 79cdb3e2c8Sopenharmony_ci f.debug_struct("Split") 80cdb3e2c8Sopenharmony_ci .field("string", &self.string) 81cdb3e2c8Sopenharmony_ci .field("pat", &self.pat) 82cdb3e2c8Sopenharmony_ci .finish() 83cdb3e2c8Sopenharmony_ci } 84cdb3e2c8Sopenharmony_ci} 85cdb3e2c8Sopenharmony_ci 86cdb3e2c8Sopenharmony_ciimpl<P> DoubleEndedIterator for Split<'_, P> 87cdb3e2c8Sopenharmony_ciwhere 88cdb3e2c8Sopenharmony_ci P: Pattern, 89cdb3e2c8Sopenharmony_ci{ 90cdb3e2c8Sopenharmony_ci fn next_back(&mut self) -> Option<Self::Item> { 91cdb3e2c8Sopenharmony_ci impl_next!(self, rsplit_once_raw, |(prefix, suffix)| (suffix, prefix)) 92cdb3e2c8Sopenharmony_ci } 93cdb3e2c8Sopenharmony_ci} 94cdb3e2c8Sopenharmony_ci 95cdb3e2c8Sopenharmony_ciimpl<P> FusedIterator for Split<'_, P> where P: Pattern {} 96cdb3e2c8Sopenharmony_ci 97cdb3e2c8Sopenharmony_ciimpl<'a, P> Iterator for Split<'a, P> 98cdb3e2c8Sopenharmony_ciwhere 99cdb3e2c8Sopenharmony_ci P: Pattern, 100cdb3e2c8Sopenharmony_ci{ 101cdb3e2c8Sopenharmony_ci type Item = &'a RawOsStr; 102cdb3e2c8Sopenharmony_ci 103cdb3e2c8Sopenharmony_ci #[inline] 104cdb3e2c8Sopenharmony_ci fn last(mut self) -> Option<Self::Item> { 105cdb3e2c8Sopenharmony_ci self.next_back() 106cdb3e2c8Sopenharmony_ci } 107cdb3e2c8Sopenharmony_ci 108cdb3e2c8Sopenharmony_ci fn next(&mut self) -> Option<Self::Item> { 109cdb3e2c8Sopenharmony_ci impl_next!(self, split_once_raw, convert::identity) 110cdb3e2c8Sopenharmony_ci } 111cdb3e2c8Sopenharmony_ci} 112