Skip to content

Instantly share code, notes, and snippets.

@mo-xiaoming
Created October 31, 2022 14:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mo-xiaoming/b027670d5fe87341cd28593d27aeabe6 to your computer and use it in GitHub Desktop.
Save mo-xiaoming/b027670d5fe87341cd28593d27aeabe6 to your computer and use it in GitHub Desktop.
Rust iterator for user defined type
#![allow(dead_code, unused)]
#[derive(Debug, Default, Clone, std::hash::Hash, PartialEq, Eq, PartialOrd, Ord)]
struct Pair {
first: i32,
second: i32,
}
impl Pair {
fn new(first: i32, second: i32) -> Self {
Self { first, second}
}
fn iter(&self) -> Iter {
Iter {pair: self, idx: 0}
}
fn iter_mut(&mut self) -> std::iter::Chain<std::iter::Once<&mut i32>, std::iter::Once<&mut i32>> {
use std::iter::once;
once(&mut self.first).chain(once(&mut self.second))
}
}
impl IntoIterator for Pair {
type Item = i32;
type IntoIter = IntoIter;
fn into_iter(self) -> Self::IntoIter {
IntoIter { pair: self, idx : 0}
}
}
struct IntoIter {
pair: Pair,
idx: usize,
}
impl Iterator for IntoIter {
type Item = i32;
fn next(&mut self) -> Option<Self::Item> {
let r = match self.idx {
0 => self.pair.first,
1 => self.pair.second,
_ => return None
};
self.idx += 1;
Some(r)
}
}
impl<'a> IntoIterator for &'a Pair {
type Item = &'a i32;
type IntoIter = Iter<'a>;
fn into_iter(self) -> Self::IntoIter {
Iter{ pair: self, idx : 0} }
}
struct Iter<'a> {
pair: &'a Pair,
idx: usize,
}
impl<'a> Iterator for Iter<'a> {
type Item = &'a i32;
fn next(&mut self) -> Option<Self::Item> {
let r = match self.idx {
0 => &self.pair.first,
1 => &self.pair.second,
_ => return None
};
self.idx += 1;
Some(r)
}
}
impl<'a> IntoIterator for &'a mut Pair {
type Item = &'a mut i32;
type IntoIter = std::iter::Chain<std::iter::Once<&'a mut i32>, std::iter::Once<&'a mut i32>>;
fn into_iter(self) -> Self::IntoIter {
self.iter_mut()
}
}
#[cfg(test)]
mod test {
use super::*;
fn good_citizen<T>(_: T) where T: std::fmt::Debug + Default + Clone + std::hash::Hash + PartialEq + PartialOrd + Eq + Ord + Send + Sync {}
#[test]
fn being_good_citizen() { good_citizen(Pair::new(0, 0)) }
#[test]
fn user_defined() {
let pair = Pair::new(1, 2);
for i in pair { let _ = i; }
let pair = Pair::new(1, 2);
for i in pair.into_iter() { let _ = i; }
let pair = Pair::new(1, 2);
for i in &pair { let _ = i; }
let pair = Pair::new(1, 2);
for i in pair.iter() { let _ = i; }
let mut pair = Pair::new(1, 2);
for i in &mut pair { let _ = i; }
let mut pair = Pair::new(1, 2);
for i in pair.iter_mut() { let _ = i; }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment