Skip to content

Commit ac5f8e6

Browse files
committed
impl map for non empty vec
1 parent b8a5042 commit ac5f8e6

File tree

3 files changed

+101
-15
lines changed

3 files changed

+101
-15
lines changed

src/refined.rs

+1-14
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,15 @@ use crate::rule::Rule;
33
use serde::{Deserialize, Deserializer, Serialize, Serializer};
44
use std::fmt::{Display, Formatter};
55
use std::marker::PhantomData;
6-
use std::ops::Deref;
76

87
/// Refined is a versatile type in ensuring that `T` satisfies the conditions of `RULE` (predicate type)
98
/// # Example
109
/// ```rust
11-
/// # use std::ops::Deref;
1210
/// use refined_type::rule::{NonEmptyString, NonEmptyStringRule};
1311
/// use refined_type::Refined;
1412
///
1513
/// let non_empty_string_result = Refined::<NonEmptyStringRule>::new("Hello World".to_string());
16-
/// assert_eq!(non_empty_string_result.unwrap().deref(), "Hello World");
14+
/// assert_eq!(non_empty_string_result.unwrap().into_value(), "Hello World");
1715
///
1816
/// let empty_string_result = Refined::<NonEmptyStringRule>::new("".to_string());
1917
/// assert!(empty_string_result.is_err())
@@ -76,17 +74,6 @@ where
7674
}
7775
}
7876

79-
impl<RULE, T> Deref for Refined<RULE>
80-
where
81-
RULE: Rule<Item = T>,
82-
{
83-
type Target = T;
84-
85-
fn deref(&self) -> &Self::Target {
86-
&self.value
87-
}
88-
}
89-
9077
impl<RULE, T> Display for Refined<RULE>
9178
where
9279
RULE: Rule<Item = T>,

src/rule/empty.rs

+33
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@ use crate::Refined;
44

55
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
66
use std::fmt::Debug;
7+
use std::iter::Map;
78
use std::marker::PhantomData;
89
use std::ops::Add;
10+
use std::vec::IntoIter;
911

1012
pub type Empty<T> = Refined<EmptyRule<T>>;
1113

@@ -59,6 +61,37 @@ impl<T> EmptyDefinition for Vec<T> {
5961
}
6062
}
6163

64+
impl<'a, T> EmptyDefinition for std::slice::Iter<'a, T> {
65+
fn empty(&self) -> bool {
66+
self.len() == 0
67+
}
68+
}
69+
70+
impl<T> EmptyDefinition for IntoIter<T> {
71+
fn empty(&self) -> bool {
72+
self.len() == 0
73+
}
74+
}
75+
76+
impl<F, B, I: ExactSizeIterator> EmptyDefinition for Map<I, F>
77+
where
78+
F: FnMut(I::Item) -> B,
79+
{
80+
fn empty(&self) -> bool {
81+
self.len() == 0
82+
}
83+
}
84+
85+
// impl<I, F> EmptyDefinition for std::iter::Map<I, F>
86+
// where
87+
// Self: Sized,
88+
// I: Iterator + EmptyDefinition,
89+
// {
90+
// fn empty(&self) -> bool {
91+
// true
92+
// }
93+
// }
94+
6295
impl<T> EmptyDefinition for HashSet<T> {
6396
fn empty(&self) -> bool {
6497
self.is_empty()

src/rule/non_empty/non_empty_vec.rs

+67-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,64 @@
1-
use crate::rule::NonEmptyRule;
1+
use crate::rule::{EmptyDefinition, NonEmptyRule};
22
use crate::Refined;
3+
use std::iter::Map;
34

45
use std::ops::Add;
6+
use std::vec::IntoIter;
7+
8+
impl<I: ExactSizeIterator + EmptyDefinition> Refined<NonEmptyRule<I>> {
9+
pub fn map<B, F>(self, f: F) -> Refined<NonEmptyRule<Map<I, F>>>
10+
where
11+
Self: Sized,
12+
F: FnMut(I::Item) -> B,
13+
{
14+
let map_into_iter = self.into_value().map(f);
15+
Refined::new(map_into_iter)
16+
.ok()
17+
.expect("This error is always unreachable")
18+
}
19+
20+
pub fn collect<B: FromIterator<I::Item> + EmptyDefinition>(self) -> Refined<NonEmptyRule<B>>
21+
where
22+
Self: Sized,
23+
{
24+
let a: B = FromIterator::from_iter(self.into_value());
25+
Refined::new(a).ok().expect("")
26+
}
27+
}
28+
29+
pub type NonEmptyIntoIter<T> = Refined<NonEmptyIntoIterRule<T>>;
30+
pub type NonEmptyIntoIterRule<T> = NonEmptyRule<IntoIter<T>>;
31+
32+
pub type NonEmptyMap<I, F> = Refined<NonEmptyMapRule<I, F>>;
33+
pub type NonEmptyMapRule<I, F> = NonEmptyRule<Map<I, F>>;
34+
35+
// impl<T> NonEmptyIntoIter<T> {
36+
// pub fn map<B, F>(self, f: F) -> Refined<NonEmptyRule<Map<IntoIter<T>, F>>>
37+
// where
38+
// Self: Sized,
39+
// F: FnMut(T) -> B,
40+
// {
41+
// let map_into_iter = self.into_value().map(f);
42+
// Refined::new(map_into_iter)
43+
// .ok()
44+
// .expect("This error is always unreachable")
45+
// }
46+
// }
547

648
pub type NonEmptyVec<T> = Refined<NonEmptyVecRule<T>>;
749

50+
impl<T> NonEmptyVec<T>
51+
where
52+
T: EmptyDefinition,
53+
{
54+
#[allow(clippy::should_implement_trait)]
55+
pub fn into_iter(self) -> NonEmptyIntoIter<T> {
56+
Refined::new(self.into_value().into_iter())
57+
.ok()
58+
.expect("This error is always unreachable")
59+
}
60+
}
61+
862
impl<T> Add for NonEmptyVec<T> {
963
type Output = Self;
1064

@@ -38,4 +92,16 @@ mod test {
3892
assert_eq!(ne_vec.into_value(), vec![1, 2, 3, 4, 5, 6]);
3993
Ok(())
4094
}
95+
96+
#[test]
97+
fn test_into_iter() -> anyhow::Result<()> {
98+
let ne_vec = NonEmptyVec::new(vec![1, 2, 3])?;
99+
let ne_vec = ne_vec
100+
.into_iter()
101+
.map(|n| n * 2)
102+
.map(|n| n * 3)
103+
.collect::<Vec<_>>();
104+
assert_eq!(ne_vec.into_value(), vec![6, 12, 18]);
105+
Ok(())
106+
}
41107
}

0 commit comments

Comments
 (0)