Use TryFrom rather than panicking From implementations to do attribute conversion.

Now that it's landed in stable and all.
This commit is contained in:
Bodil Stokke 2019-04-12 18:46:33 +01:00
parent 36c95b0b8e
commit 5334d783f2
8 changed files with 319 additions and 275 deletions

View File

@ -6,6 +6,17 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic
Versioning](http://semver.org/spec/v2.0.0.html).
## [Unreleased]
### Changed
- Attribute type conversion is now using the newly stabilised `TryFrom` instead
of `From`, to avoid relying on panicking `From` implementations to detect
conversion errors, though the conversions inside the macro will still panic if
they fail. The appropriate `TryFrom` implementations have been added to
`Class`, `Id`, `SpacedList` and `SpacedSet`, and the corresponding `From`
implementations have been removed.
## [0.2.0] - 2019-03-16
### Added

View File

@ -233,7 +233,7 @@ impl Element {
value => {
let value = process_value(value);
body.extend(quote!(
element.attrs.#key = Some(std::convert::Into::into(#value));
element.attrs.#key = Some(std::convert::TryInto::try_into(#value).unwrap());
));
}
}
@ -364,7 +364,7 @@ impl Element {
value => {
let value = process_value(value);
set_attrs.extend(quote!(
element.attrs.#key = Some(std::convert::Into::into(#value));
element.attrs.#key = Some(std::convert::TryInto::try_into(#value).unwrap());
));
}
}

View File

@ -64,7 +64,7 @@ macro_rules! declare_events_struct {
$(
.chain(
iter::once(self.$name.take())
.filter(|value| value.is_some())
.filter(Option::is_some)
.map(|value| (stringify!($name), value.unwrap()))
)
)*

View File

@ -89,11 +89,12 @@
//! ## Example
//!
//! ```
//! # use std::convert::{TryFrom, TryInto};
//! # use typed_html::html;
//! # use typed_html::dom::DOMTree;
//! # use typed_html::types::{Class, SpacedSet};
//! # fn main() {
//! let classList: SpacedSet<Class> = ["foo", "bar", "baz"].into();
//! # fn main() -> Result<(), &'static str> {
//! let classList: SpacedSet<Class> = ["foo", "bar", "baz"].try_into()?;
//! # let doc: DOMTree<String> =
//! html!(
//! <div>
@ -101,11 +102,11 @@
//! <div class=["foo", "bar", "baz"] /> // uses From<[&str, &str, &str]>
//! <div class=classList /> // uses a variable in scope
//! <div class={ // evaluates a code block
//! SpacedSet::from(["foo", "bar", "baz"])
//! SpacedSet::try_from(["foo", "bar", "baz"])?
//! } />
//! </div>
//! )
//! # ;}
//! # ; Ok(()) }
//! ```
//!
//! # Generated Nodes

View File

@ -1,3 +1,5 @@
use std::borrow::Borrow;
use std::convert::TryFrom;
use std::fmt::{Display, Error, Formatter};
use std::ops::Deref;
use std::str::FromStr;
@ -19,11 +21,22 @@ pub struct Class(String);
impl Class {
/// Construct a new class name from a string.
///
/// Returns `Err` if the provided string is invalid.
pub fn try_new<S: Into<String>>(id: S) -> Result<Self, &'static str> {
let id = id.into();
{
let mut chars = id.chars();
/// Panics if the provided string is invalid.
pub fn new<S: Borrow<str>>(s: S) -> Self {
let s = s.borrow();
Self::from_str(s).unwrap_or_else(|err| {
panic!(
"typed_html::types::Class: {:?} is not a valid class name: {}",
s, err
)
})
}
}
impl FromStr for Class {
type Err = &'static str;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let mut chars = s.chars();
match chars.next() {
None => return Err("class name cannot be empty"),
Some(c) if !c.is_alphabetic() => {
@ -33,33 +46,10 @@ impl Class {
}
for c in chars {
if !c.is_alphanumeric() && c != '_' && c != '-' && c != '.' {
return Err(
"class name can only contain alphanumerics, dash, dot and underscore",
);
return Err("class name can only contain alphanumerics, dash, dot and underscore");
}
}
}
Ok(Class(id))
}
/// Construct a new class name from a string.
///
/// Panics if the provided string is invalid.
pub fn new<S: Into<String>>(id: S) -> Self {
let id = id.into();
Self::try_new(id.clone()).unwrap_or_else(|err| {
panic!(
"typed_html::types::Class: {:?} is not a valid class name: {}",
id, err
)
})
}
}
impl FromStr for Class {
type Err = &'static str;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Class::try_new(s)
Ok(Class(s.to_string()))
}
}
@ -69,9 +59,10 @@ impl From<Id> for Class {
}
}
impl<'a> From<&'a str> for Class {
fn from(str: &'a str) -> Self {
Class::from_str(str).unwrap()
impl<'a> TryFrom<&'a str> for Class {
type Error = &'static str;
fn try_from(str: &'a str) -> Result<Self, Self::Error> {
Class::from_str(str)
}
}

View File

@ -1,3 +1,5 @@
use std::borrow::Borrow;
use std::convert::TryFrom;
use std::fmt::{Display, Error, Formatter};
use std::ops::Deref;
use std::str::FromStr;
@ -19,10 +21,18 @@ pub struct Id(String);
impl Id {
/// Construct a new ID from a string.
///
/// Returns `Err` if the provided string is invalid.
pub fn try_new<S: Into<String>>(id: S) -> Result<Self, &'static str> {
let id = id.into();
{
/// Panics if the provided string is invalid.
pub fn new<S: Borrow<str>>(id: S) -> Self {
let id = id.borrow();
Self::from_str(id).unwrap_or_else(|err| {
panic!("typed_html::types::Id: {:?} is not a valid ID: {}", id, err)
})
}
}
impl FromStr for Id {
type Err = &'static str;
fn from_str(id: &str) -> Result<Self, Self::Err> {
let mut chars = id.chars();
match chars.next() {
None => return Err("ID cannot be empty"),
@ -36,31 +46,14 @@ impl Id {
return Err("ID can only contain alphanumerics, dash, dot and underscore");
}
}
}
Ok(Id(id))
}
/// Construct a new ID from a string.
///
/// Panics if the provided string is invalid.
pub fn new<S: Into<String>>(id: S) -> Self {
let id = id.into();
Self::try_new(id.clone()).unwrap_or_else(|err| {
panic!("typed_html::types::Id: {:?} is not a valid ID: {}", id, err)
})
Ok(Id(id.to_string()))
}
}
impl FromStr for Id {
type Err = &'static str;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Id::try_new(s)
}
}
impl<'a> From<&'a str> for Id {
fn from(str: &'a str) -> Self {
Id::from_str(str).unwrap()
impl<'a> TryFrom<&'a str> for Id {
type Error = &'static str;
fn try_from(str: &'a str) -> Result<Self, Self::Error> {
Id::from_str(str)
}
}

View File

@ -1,3 +1,4 @@
use std::convert::{TryFrom, TryInto};
use std::fmt::{Debug, Display, Error, Formatter};
use std::iter::FromIterator;
use std::ops::{Deref, DerefMut};
@ -18,6 +19,24 @@ impl<A> SpacedList<A> {
pub fn new() -> Self {
SpacedList(Vec::new())
}
/// Add a value to the `SpacedList`, converting it as necessary.
///
/// Panics if the conversion fails.
pub fn add<T: TryInto<A>>(&mut self, value: T)
where
<T as TryInto<A>>::Error: Debug,
{
self.0.push(value.try_into().unwrap())
}
/// Add a value to the `SpacedList`, converting it as necessary.
///
/// Returns an error if the conversion fails.
pub fn try_add<T: TryInto<A>>(&mut self, value: T) -> Result<(), <T as TryInto<A>>::Error> {
self.0.push(value.try_into()?);
Ok(())
}
}
impl<A> Default for SpacedList<A> {
@ -44,12 +63,13 @@ impl<'a, A: 'a + Clone> FromIterator<&'a A> for SpacedList<A> {
}
}
impl<'a, A: FromStr> From<&'a str> for SpacedList<A>
impl<'a, A> TryFrom<&'a str> for SpacedList<A>
where
<A as FromStr>::Err: Debug,
A: FromStr,
{
fn from(s: &'a str) -> Self {
Self::from_iter(s.split_whitespace().map(|s| FromStr::from_str(s).unwrap()))
type Error = <A as FromStr>::Err;
fn try_from(s: &'a str) -> Result<Self, Self::Error> {
s.split_whitespace().map(FromStr::from_str).collect()
}
}
@ -85,80 +105,84 @@ impl<A: Debug> Debug for SpacedList<A> {
}
}
impl<'a, 'b, A: FromStr> From<(&'a str, &'b str)> for SpacedList<A>
impl<'a, 'b, A> TryFrom<(&'a str, &'b str)> for SpacedList<A>
where
<A as FromStr>::Err: Debug,
A: FromStr,
{
fn from(s: (&str, &str)) -> Self {
type Error = <A as FromStr>::Err;
fn try_from(s: (&str, &str)) -> Result<Self, Self::Error> {
let mut list = Self::new();
list.push(FromStr::from_str(s.0).unwrap());
list.push(FromStr::from_str(s.1).unwrap());
list
list.push(FromStr::from_str(s.0)?);
list.push(FromStr::from_str(s.1)?);
Ok(list)
}
}
impl<'a, 'b, 'c, A: FromStr> From<(&'a str, &'b str, &'c str)> for SpacedList<A>
impl<'a, 'b, 'c, A> TryFrom<(&'a str, &'b str, &'c str)> for SpacedList<A>
where
<A as FromStr>::Err: Debug,
A: FromStr,
{
fn from(s: (&str, &str, &str)) -> Self {
type Error = <A as FromStr>::Err;
fn try_from(s: (&str, &str, &str)) -> Result<Self, Self::Error> {
let mut list = Self::new();
list.push(FromStr::from_str(s.0).unwrap());
list.push(FromStr::from_str(s.1).unwrap());
list.push(FromStr::from_str(s.2).unwrap());
list
list.push(FromStr::from_str(s.0)?);
list.push(FromStr::from_str(s.1)?);
list.push(FromStr::from_str(s.2)?);
Ok(list)
}
}
impl<'a, 'b, 'c, 'd, A: FromStr> From<(&'a str, &'b str, &'c str, &'d str)> for SpacedList<A>
impl<'a, 'b, 'c, 'd, A> TryFrom<(&'a str, &'b str, &'c str, &'d str)> for SpacedList<A>
where
<A as FromStr>::Err: Debug,
A: FromStr,
{
fn from(s: (&str, &str, &str, &str)) -> Self {
type Error = <A as FromStr>::Err;
fn try_from(s: (&str, &str, &str, &str)) -> Result<Self, Self::Error> {
let mut list = Self::new();
list.push(FromStr::from_str(s.0).unwrap());
list.push(FromStr::from_str(s.1).unwrap());
list.push(FromStr::from_str(s.2).unwrap());
list.push(FromStr::from_str(s.3).unwrap());
list
list.push(FromStr::from_str(s.0)?);
list.push(FromStr::from_str(s.1)?);
list.push(FromStr::from_str(s.2)?);
list.push(FromStr::from_str(s.3)?);
Ok(list)
}
}
impl<'a, 'b, 'c, 'd, 'e, A: FromStr> From<(&'a str, &'b str, &'c str, &'d str, &'e str)>
impl<'a, 'b, 'c, 'd, 'e, A> TryFrom<(&'a str, &'b str, &'c str, &'d str, &'e str)> for SpacedList<A>
where
A: FromStr,
{
type Error = <A as FromStr>::Err;
fn try_from(s: (&str, &str, &str, &str, &str)) -> Result<Self, Self::Error> {
let mut list = Self::new();
list.push(FromStr::from_str(s.0)?);
list.push(FromStr::from_str(s.1)?);
list.push(FromStr::from_str(s.2)?);
list.push(FromStr::from_str(s.3)?);
list.push(FromStr::from_str(s.4)?);
Ok(list)
}
}
impl<'a, 'b, 'c, 'd, 'e, 'f, A> TryFrom<(&'a str, &'b str, &'c str, &'d str, &'e str, &'f str)>
for SpacedList<A>
where
<A as FromStr>::Err: Debug,
A: FromStr,
{
fn from(s: (&str, &str, &str, &str, &str)) -> Self {
type Error = <A as FromStr>::Err;
fn try_from(s: (&str, &str, &str, &str, &str, &str)) -> Result<Self, Self::Error> {
let mut list = Self::new();
list.push(FromStr::from_str(s.0).unwrap());
list.push(FromStr::from_str(s.1).unwrap());
list.push(FromStr::from_str(s.2).unwrap());
list.push(FromStr::from_str(s.3).unwrap());
list.push(FromStr::from_str(s.4).unwrap());
list
list.push(FromStr::from_str(s.0)?);
list.push(FromStr::from_str(s.1)?);
list.push(FromStr::from_str(s.2)?);
list.push(FromStr::from_str(s.3)?);
list.push(FromStr::from_str(s.4)?);
list.push(FromStr::from_str(s.5)?);
Ok(list)
}
}
impl<'a, 'b, 'c, 'd, 'e, 'f, A: FromStr>
From<(&'a str, &'b str, &'c str, &'d str, &'e str, &'f str)> for SpacedList<A>
where
<A as FromStr>::Err: Debug,
{
fn from(s: (&str, &str, &str, &str, &str, &str)) -> Self {
let mut list = Self::new();
list.push(FromStr::from_str(s.0).unwrap());
list.push(FromStr::from_str(s.1).unwrap());
list.push(FromStr::from_str(s.2).unwrap());
list.push(FromStr::from_str(s.3).unwrap());
list.push(FromStr::from_str(s.4).unwrap());
list.push(FromStr::from_str(s.5).unwrap());
list
}
}
impl<'a, 'b, 'c, 'd, 'e, 'f, 'g, A: FromStr>
From<(
impl<'a, 'b, 'c, 'd, 'e, 'f, 'g, A>
TryFrom<(
&'a str,
&'b str,
&'c str,
@ -168,23 +192,24 @@ impl<'a, 'b, 'c, 'd, 'e, 'f, 'g, A: FromStr>
&'g str,
)> for SpacedList<A>
where
<A as FromStr>::Err: Debug,
A: FromStr,
{
fn from(s: (&str, &str, &str, &str, &str, &str, &str)) -> Self {
type Error = <A as FromStr>::Err;
fn try_from(s: (&str, &str, &str, &str, &str, &str, &str)) -> Result<Self, Self::Error> {
let mut list = Self::new();
list.push(FromStr::from_str(s.0).unwrap());
list.push(FromStr::from_str(s.1).unwrap());
list.push(FromStr::from_str(s.2).unwrap());
list.push(FromStr::from_str(s.3).unwrap());
list.push(FromStr::from_str(s.4).unwrap());
list.push(FromStr::from_str(s.5).unwrap());
list.push(FromStr::from_str(s.6).unwrap());
list
list.push(FromStr::from_str(s.0)?);
list.push(FromStr::from_str(s.1)?);
list.push(FromStr::from_str(s.2)?);
list.push(FromStr::from_str(s.3)?);
list.push(FromStr::from_str(s.4)?);
list.push(FromStr::from_str(s.5)?);
list.push(FromStr::from_str(s.6)?);
Ok(list)
}
}
impl<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, A: FromStr>
From<(
impl<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, A>
TryFrom<(
&'a str,
&'b str,
&'c str,
@ -195,30 +220,32 @@ impl<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, A: FromStr>
&'h str,
)> for SpacedList<A>
where
<A as FromStr>::Err: Debug,
A: FromStr,
{
fn from(s: (&str, &str, &str, &str, &str, &str, &str, &str)) -> Self {
type Error = <A as FromStr>::Err;
fn try_from(s: (&str, &str, &str, &str, &str, &str, &str, &str)) -> Result<Self, Self::Error> {
let mut list = Self::new();
list.push(FromStr::from_str(s.0).unwrap());
list.push(FromStr::from_str(s.1).unwrap());
list.push(FromStr::from_str(s.2).unwrap());
list.push(FromStr::from_str(s.3).unwrap());
list.push(FromStr::from_str(s.4).unwrap());
list.push(FromStr::from_str(s.5).unwrap());
list.push(FromStr::from_str(s.6).unwrap());
list.push(FromStr::from_str(s.7).unwrap());
list
list.push(FromStr::from_str(s.0)?);
list.push(FromStr::from_str(s.1)?);
list.push(FromStr::from_str(s.2)?);
list.push(FromStr::from_str(s.3)?);
list.push(FromStr::from_str(s.4)?);
list.push(FromStr::from_str(s.5)?);
list.push(FromStr::from_str(s.6)?);
list.push(FromStr::from_str(s.7)?);
Ok(list)
}
}
macro_rules! spacedlist_from_array {
($num:tt) => {
impl<'a, A: FromStr> From<[&'a str; $num]> for SpacedList<A>
impl<'a, A> TryFrom<[&'a str; $num]> for SpacedList<A>
where
<A as FromStr>::Err: Debug,
A: FromStr,
{
fn from(s: [&str; $num]) -> Self {
Self::from_iter(s.into_iter().map(|s| FromStr::from_str(*s).unwrap()))
type Error = <A as FromStr>::Err;
fn try_from(s: [&str; $num]) -> Result<Self, Self::Error> {
s.into_iter().map(|s| FromStr::from_str(*s)).collect()
}
}
};

View File

@ -1,4 +1,5 @@
use std::collections::BTreeSet;
use std::convert::{TryFrom, TryInto};
use std::fmt::{Debug, Display, Error, Formatter};
use std::iter::FromIterator;
use std::ops::{Deref, DerefMut};
@ -12,18 +13,18 @@ use std::str::FromStr;
/// # Examples
///
/// ```
/// # use std::convert::From;
/// # use std::convert::{TryFrom, TryInto};
/// use typed_html::types::{Class, SpacedSet};
///
/// # fn main() {
/// let classList: SpacedSet<Class> = "foo bar baz".into();
/// let classList: SpacedSet<Class> = ["foo", "bar", "baz"].into();
/// let classList: SpacedSet<Class> = ("foo", "bar", "baz").into();
/// # fn main() -> Result<(), &'static str> {
/// let classList: SpacedSet<Class> = "foo bar baz".try_into()?;
/// let classList: SpacedSet<Class> = ["foo", "bar", "baz"].try_into()?;
/// let classList: SpacedSet<Class> = ("foo", "bar", "baz").try_into()?;
///
/// let classList1: SpacedSet<Class> = "foo bar foo".into();
/// let classList2: SpacedSet<Class> = "bar foo bar".into();
/// let classList1: SpacedSet<Class> = "foo bar foo".try_into()?;
/// let classList2: SpacedSet<Class> = "bar foo bar".try_into()?;
/// assert_eq!(classList1, classList2);
/// # }
/// # Ok(()) }
/// ```
#[derive(Clone, PartialEq, Eq, Hash)]
pub struct SpacedSet<A: Ord>(BTreeSet<A>);
@ -34,9 +35,21 @@ impl<A: Ord> SpacedSet<A> {
SpacedSet(BTreeSet::new())
}
/// Add a value to the `SpacedSet`.
pub fn add<T: Into<A>>(&mut self, value: T) -> bool {
self.0.insert(value.into())
/// Add a value to the `SpacedSet`, converting it as necessary.
///
/// Panics if the conversion fails.
pub fn add<T: TryInto<A>>(&mut self, value: T) -> bool
where
<T as TryInto<A>>::Error: Debug,
{
self.0.insert(value.try_into().unwrap())
}
/// Add a value to the `SpacedSet`, converting it as necessary.
///
/// Returns an error if the conversion fails.
pub fn try_add<T: TryInto<A>>(&mut self, value: T) -> Result<bool, <T as TryInto<A>>::Error> {
Ok(self.0.insert(value.try_into()?))
}
}
@ -77,12 +90,13 @@ where
}
}
impl<'a, A: Ord + FromStr> From<&'a str> for SpacedSet<A>
impl<'a, A> TryFrom<&'a str> for SpacedSet<A>
where
<A as FromStr>::Err: Debug,
A: Ord + FromStr,
{
fn from(s: &'a str) -> Self {
Self::from_iter(s.split_whitespace().map(|s| FromStr::from_str(s).unwrap()))
type Error = <A as FromStr>::Err;
fn try_from(s: &'a str) -> Result<Self, Self::Error> {
s.split_whitespace().map(FromStr::from_str).collect()
}
}
@ -118,80 +132,84 @@ impl<A: Ord + Debug> Debug for SpacedSet<A> {
}
}
impl<'a, 'b, A: Ord + FromStr> From<(&'a str, &'b str)> for SpacedSet<A>
impl<'a, 'b, A> TryFrom<(&'a str, &'b str)> for SpacedSet<A>
where
<A as FromStr>::Err: Debug,
A: Ord + FromStr,
{
fn from(s: (&str, &str)) -> Self {
type Error = <A as FromStr>::Err;
fn try_from(s: (&str, &str)) -> Result<Self, Self::Error> {
let mut list = Self::new();
list.insert(FromStr::from_str(s.0).unwrap());
list.insert(FromStr::from_str(s.1).unwrap());
list
list.insert(FromStr::from_str(s.0)?);
list.insert(FromStr::from_str(s.1)?);
Ok(list)
}
}
impl<'a, 'b, 'c, A: Ord + FromStr> From<(&'a str, &'b str, &'c str)> for SpacedSet<A>
impl<'a, 'b, 'c, A> TryFrom<(&'a str, &'b str, &'c str)> for SpacedSet<A>
where
<A as FromStr>::Err: Debug,
A: Ord + FromStr,
{
fn from(s: (&str, &str, &str)) -> Self {
type Error = <A as FromStr>::Err;
fn try_from(s: (&str, &str, &str)) -> Result<Self, Self::Error> {
let mut list = Self::new();
list.insert(FromStr::from_str(s.0).unwrap());
list.insert(FromStr::from_str(s.1).unwrap());
list.insert(FromStr::from_str(s.2).unwrap());
list
list.insert(FromStr::from_str(s.0)?);
list.insert(FromStr::from_str(s.1)?);
list.insert(FromStr::from_str(s.2)?);
Ok(list)
}
}
impl<'a, 'b, 'c, 'd, A: Ord + FromStr> From<(&'a str, &'b str, &'c str, &'d str)> for SpacedSet<A>
impl<'a, 'b, 'c, 'd, A> TryFrom<(&'a str, &'b str, &'c str, &'d str)> for SpacedSet<A>
where
<A as FromStr>::Err: Debug,
A: Ord + FromStr,
{
fn from(s: (&str, &str, &str, &str)) -> Self {
type Error = <A as FromStr>::Err;
fn try_from(s: (&str, &str, &str, &str)) -> Result<Self, Self::Error> {
let mut list = Self::new();
list.insert(FromStr::from_str(s.0).unwrap());
list.insert(FromStr::from_str(s.1).unwrap());
list.insert(FromStr::from_str(s.2).unwrap());
list.insert(FromStr::from_str(s.3).unwrap());
list
list.insert(FromStr::from_str(s.0)?);
list.insert(FromStr::from_str(s.1)?);
list.insert(FromStr::from_str(s.2)?);
list.insert(FromStr::from_str(s.3)?);
Ok(list)
}
}
impl<'a, 'b, 'c, 'd, 'e, A: Ord + FromStr> From<(&'a str, &'b str, &'c str, &'d str, &'e str)>
impl<'a, 'b, 'c, 'd, 'e, A> TryFrom<(&'a str, &'b str, &'c str, &'d str, &'e str)> for SpacedSet<A>
where
A: Ord + FromStr,
{
type Error = <A as FromStr>::Err;
fn try_from(s: (&str, &str, &str, &str, &str)) -> Result<Self, Self::Error> {
let mut list = Self::new();
list.insert(FromStr::from_str(s.0)?);
list.insert(FromStr::from_str(s.1)?);
list.insert(FromStr::from_str(s.2)?);
list.insert(FromStr::from_str(s.3)?);
list.insert(FromStr::from_str(s.4)?);
Ok(list)
}
}
impl<'a, 'b, 'c, 'd, 'e, 'f, A> TryFrom<(&'a str, &'b str, &'c str, &'d str, &'e str, &'f str)>
for SpacedSet<A>
where
<A as FromStr>::Err: Debug,
A: Ord + FromStr,
{
fn from(s: (&str, &str, &str, &str, &str)) -> Self {
type Error = <A as FromStr>::Err;
fn try_from(s: (&str, &str, &str, &str, &str, &str)) -> Result<Self, Self::Error> {
let mut list = Self::new();
list.insert(FromStr::from_str(s.0).unwrap());
list.insert(FromStr::from_str(s.1).unwrap());
list.insert(FromStr::from_str(s.2).unwrap());
list.insert(FromStr::from_str(s.3).unwrap());
list.insert(FromStr::from_str(s.4).unwrap());
list
list.insert(FromStr::from_str(s.0)?);
list.insert(FromStr::from_str(s.1)?);
list.insert(FromStr::from_str(s.2)?);
list.insert(FromStr::from_str(s.3)?);
list.insert(FromStr::from_str(s.4)?);
list.insert(FromStr::from_str(s.5)?);
Ok(list)
}
}
impl<'a, 'b, 'c, 'd, 'e, 'f, A: Ord + FromStr>
From<(&'a str, &'b str, &'c str, &'d str, &'e str, &'f str)> for SpacedSet<A>
where
<A as FromStr>::Err: Debug,
{
fn from(s: (&str, &str, &str, &str, &str, &str)) -> Self {
let mut list = Self::new();
list.insert(FromStr::from_str(s.0).unwrap());
list.insert(FromStr::from_str(s.1).unwrap());
list.insert(FromStr::from_str(s.2).unwrap());
list.insert(FromStr::from_str(s.3).unwrap());
list.insert(FromStr::from_str(s.4).unwrap());
list.insert(FromStr::from_str(s.5).unwrap());
list
}
}
impl<'a, 'b, 'c, 'd, 'e, 'f, 'g, A: Ord + FromStr>
From<(
impl<'a, 'b, 'c, 'd, 'e, 'f, 'g, A>
TryFrom<(
&'a str,
&'b str,
&'c str,
@ -201,23 +219,24 @@ impl<'a, 'b, 'c, 'd, 'e, 'f, 'g, A: Ord + FromStr>
&'g str,
)> for SpacedSet<A>
where
<A as FromStr>::Err: Debug,
A: Ord + FromStr,
{
fn from(s: (&str, &str, &str, &str, &str, &str, &str)) -> Self {
type Error = <A as FromStr>::Err;
fn try_from(s: (&str, &str, &str, &str, &str, &str, &str)) -> Result<Self, Self::Error> {
let mut list = Self::new();
list.insert(FromStr::from_str(s.0).unwrap());
list.insert(FromStr::from_str(s.1).unwrap());
list.insert(FromStr::from_str(s.2).unwrap());
list.insert(FromStr::from_str(s.3).unwrap());
list.insert(FromStr::from_str(s.4).unwrap());
list.insert(FromStr::from_str(s.5).unwrap());
list.insert(FromStr::from_str(s.6).unwrap());
list
list.insert(FromStr::from_str(s.0)?);
list.insert(FromStr::from_str(s.1)?);
list.insert(FromStr::from_str(s.2)?);
list.insert(FromStr::from_str(s.3)?);
list.insert(FromStr::from_str(s.4)?);
list.insert(FromStr::from_str(s.5)?);
list.insert(FromStr::from_str(s.6)?);
Ok(list)
}
}
impl<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, A: Ord + FromStr>
From<(
impl<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, A>
TryFrom<(
&'a str,
&'b str,
&'c str,
@ -228,63 +247,65 @@ impl<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, A: Ord + FromStr>
&'h str,
)> for SpacedSet<A>
where
<A as FromStr>::Err: Debug,
A: Ord + FromStr,
{
fn from(s: (&str, &str, &str, &str, &str, &str, &str, &str)) -> Self {
type Error = <A as FromStr>::Err;
fn try_from(s: (&str, &str, &str, &str, &str, &str, &str, &str)) -> Result<Self, Self::Error> {
let mut list = Self::new();
list.insert(FromStr::from_str(s.0).unwrap());
list.insert(FromStr::from_str(s.1).unwrap());
list.insert(FromStr::from_str(s.2).unwrap());
list.insert(FromStr::from_str(s.3).unwrap());
list.insert(FromStr::from_str(s.4).unwrap());
list.insert(FromStr::from_str(s.5).unwrap());
list.insert(FromStr::from_str(s.6).unwrap());
list.insert(FromStr::from_str(s.7).unwrap());
list
list.insert(FromStr::from_str(s.0)?);
list.insert(FromStr::from_str(s.1)?);
list.insert(FromStr::from_str(s.2)?);
list.insert(FromStr::from_str(s.3)?);
list.insert(FromStr::from_str(s.4)?);
list.insert(FromStr::from_str(s.5)?);
list.insert(FromStr::from_str(s.6)?);
list.insert(FromStr::from_str(s.7)?);
Ok(list)
}
}
macro_rules! spacedlist_from_array {
macro_rules! spacedset_from_array {
($num:tt) => {
impl<'a, A: Ord + FromStr> From<[&'a str; $num]> for SpacedSet<A>
impl<'a, A> TryFrom<[&'a str; $num]> for SpacedSet<A>
where
<A as FromStr>::Err: Debug,
A: Ord + FromStr,
{
fn from(s: [&str; $num]) -> Self {
Self::from_iter(s.into_iter().map(|s| FromStr::from_str(*s).unwrap()))
type Error = <A as FromStr>::Err;
fn try_from(s: [&str; $num]) -> Result<Self, Self::Error> {
s.into_iter().map(|s| FromStr::from_str(*s)).collect()
}
}
};
}
spacedlist_from_array!(1);
spacedlist_from_array!(2);
spacedlist_from_array!(3);
spacedlist_from_array!(4);
spacedlist_from_array!(5);
spacedlist_from_array!(6);
spacedlist_from_array!(7);
spacedlist_from_array!(8);
spacedlist_from_array!(9);
spacedlist_from_array!(10);
spacedlist_from_array!(11);
spacedlist_from_array!(12);
spacedlist_from_array!(13);
spacedlist_from_array!(14);
spacedlist_from_array!(15);
spacedlist_from_array!(16);
spacedlist_from_array!(17);
spacedlist_from_array!(18);
spacedlist_from_array!(19);
spacedlist_from_array!(20);
spacedlist_from_array!(21);
spacedlist_from_array!(22);
spacedlist_from_array!(23);
spacedlist_from_array!(24);
spacedlist_from_array!(25);
spacedlist_from_array!(26);
spacedlist_from_array!(27);
spacedlist_from_array!(28);
spacedlist_from_array!(29);
spacedlist_from_array!(30);
spacedlist_from_array!(31);
spacedlist_from_array!(32);
spacedset_from_array!(1);
spacedset_from_array!(2);
spacedset_from_array!(3);
spacedset_from_array!(4);
spacedset_from_array!(5);
spacedset_from_array!(6);
spacedset_from_array!(7);
spacedset_from_array!(8);
spacedset_from_array!(9);
spacedset_from_array!(10);
spacedset_from_array!(11);
spacedset_from_array!(12);
spacedset_from_array!(13);
spacedset_from_array!(14);
spacedset_from_array!(15);
spacedset_from_array!(16);
spacedset_from_array!(17);
spacedset_from_array!(18);
spacedset_from_array!(19);
spacedset_from_array!(20);
spacedset_from_array!(21);
spacedset_from_array!(22);
spacedset_from_array!(23);
spacedset_from_array!(24);
spacedset_from_array!(25);
spacedset_from_array!(26);
spacedset_from_array!(27);
spacedset_from_array!(28);
spacedset_from_array!(29);
spacedset_from_array!(30);
spacedset_from_array!(31);
spacedset_from_array!(32);