Skip to content

Commit ea374c0

Browse files
committed
convenient infallible unwrapper
1 parent 6af05ee commit ea374c0

File tree

4 files changed

+40
-3
lines changed

4 files changed

+40
-3
lines changed

rust/functora-tagged/README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,17 +88,18 @@ When a `Tag` type has a default `Refine` implementation that doesn't add new con
8888

8989
```rust
9090
use functora_tagged::*;
91+
use std::convert::Infallible;
9192

9293
pub enum NonNegTag {}
9394

9495
impl Refine<usize> for NonNegTag {
95-
type RefineError = ();
96+
type RefineError = Infallible;
9697
}
9798

9899
pub type NonNeg = Tagged<usize, NonNegTag>;
99100

100101
let rep = 123;
101-
let new = NonNeg::new(rep).unwrap();
102+
let new = NonNeg::new(rep).infallible();
102103

103104
assert_eq!(*new.rep(), rep);
104105
```
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
use std::convert::Infallible;
2+
3+
pub trait InfallibleInto<T> {
4+
fn infallible(self) -> T;
5+
}
6+
7+
impl<T> InfallibleInto<T> for Result<T, Infallible> {
8+
fn infallible(self) -> T {
9+
self.unwrap()
10+
}
11+
}

rust/functora-tagged/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ use std::hash::{Hash, Hasher};
66
use std::marker::PhantomData;
77
use std::ops::Deref;
88
use std::str::FromStr;
9+
pub mod infallible;
10+
pub use infallible::*;
911

1012
#[derive(Debug)]
1113
pub struct Tagged<Rep, Tag>(Rep, PhantomData<Tag>);

rust/functora-tagged/tests/integration.rs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
use derive_more::Display;
2-
use functora_tagged::{ParseError, Refine, Tagged};
2+
use functora_tagged::{
3+
InfallibleInto, ParseError, Refine, Tagged,
4+
};
35
#[cfg(feature = "serde")]
46
use serde::{Deserialize, Serialize};
7+
use std::convert::Infallible;
58
use std::error::Error;
69
use std::fmt::Debug;
710

@@ -17,6 +20,10 @@ pub type UserId = Tagged<NonEmpty<String>, UserIdTag>;
1720
pub enum EmailTag {}
1821
pub type Email = Tagged<NonEmpty<String>, EmailTag>;
1922

23+
#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Debug)]
24+
pub enum UpperTag {}
25+
pub type UpperString = Tagged<String, UpperTag>;
26+
2027
#[derive(
2128
Eq, PartialEq, Ord, PartialOrd, Clone, Debug, Display,
2229
)]
@@ -76,6 +83,15 @@ impl Refine<NonEmpty<String>> for EmailTag {
7683
}
7784
}
7885

86+
impl Refine<String> for UpperTag {
87+
type RefineError = Infallible;
88+
fn refine(
89+
rep: String,
90+
) -> Result<String, Self::RefineError> {
91+
Ok(rep.to_uppercase())
92+
}
93+
}
94+
7995
#[test]
8096
fn test_non_empty_from_str_success() {
8197
let ne: NonEmpty<String> = "hello".parse().unwrap();
@@ -154,6 +170,13 @@ fn test_tagged_clone_debug() {
154170
assert!(dbg.contains("PhantomData"));
155171
}
156172

173+
#[test]
174+
fn test_upper_string_infallible() {
175+
let tagged: UpperString =
176+
UpperString::new("test".into()).infallible();
177+
assert_eq!(tagged.rep(), "TEST");
178+
}
179+
157180
#[cfg(feature = "serde")]
158181
#[test]
159182
fn test_serde_user_id_roundtrip() {

0 commit comments

Comments
 (0)