try_from-0.3.2/.gitignore010064400007650000024000000000221262561146000135610ustar0000000000000000target Cargo.lock try_from-0.3.2/.travis.yml010064400007650000024000000000171262564646500137230ustar0000000000000000language: rust try_from-0.3.2/Cargo.toml.orig010064400007650000024000000005061337760415200144740ustar0000000000000000[package] name = "try_from" version = "0.3.2" authors = ["Derek Williams "] description = "TryFrom and TryInto traits for failable conversions that return a Result." repository = "https://github.com/derekjw/try_from" readme = "README.md" license = "MIT" [dependencies] cfg-if = "0.1" [features] no_std = [] try_from-0.3.2/Cargo.toml0000644000000015310000000000000107340ustar00# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g. crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're # editing this file be aware that the upstream Cargo.toml # will likely look very different (and much more reasonable) [package] name = "try_from" version = "0.3.2" authors = ["Derek Williams "] description = "TryFrom and TryInto traits for failable conversions that return a Result." readme = "README.md" license = "MIT" repository = "https://github.com/derekjw/try_from" [dependencies.cfg-if] version = "0.1" [features] no_std = [] try_from-0.3.2/LICENSE010064400007650000024000000020711262561426400126110ustar0000000000000000The MIT License (MIT) Copyright (c) 2015 Derek Williams Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. try_from-0.3.2/README.md010064400007650000024000000005761262564646500131030ustar0000000000000000# try_from [![Travis Build Status](https://travis-ci.org/derekjw/try_from.svg?branch=master)](https://travis-ci.org/derekjw/try_from) [![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE) [![crates.io](http://meritbadge.herokuapp.com/try_from)](https://crates.io/crates/try_from) TryFrom and TryInto traits for failable conversions that return a Result. try_from-0.3.2/src/char.rs010064400007650000024000000065251337734512500136700ustar0000000000000000// Conversion between machine integers and `char`. cfg_if! ( if #[cfg(feature="no_std")] { use core::char; use core::fmt::{self, Display, Formatter}; } else { use std::char; use std::error::Error; use std::fmt::{self, Display, Formatter}; } ); use {TryFrom, TryFromIntError, Void}; impl TryFrom for T where T: TryFrom, { type Err = TryFromIntError; fn try_from(c: char) -> Result { T::try_from(c as u32) } } #[test] fn test_char_to_int() { assert_eq!(u8::try_from('~'), Ok(0x7e)); assert_eq!(u8::try_from('\u{100}'), Err(TryFromIntError::Overflow)); } macro_rules! impl_infallible { ($($ty:ty),*) => { $( impl TryFrom<$ty> for char { type Err = Void; fn try_from (n: $ty) -> Result { Ok(n as char) } } )* }; } impl_infallible!(u8, char); #[test] fn test_to_char_infallible() { assert_eq!(char::try_from(0x7e), Ok('~')); assert_eq!(char::try_from('~'), Ok('~')); } macro_rules! impl_int_to_char { ($($ty:ty),*) => { $( impl TryFrom<$ty> for char { type Err = TryFromIntToCharError; fn try_from (n: $ty) -> Result { match u32::try_from(n)? { n @ 0...0x10ffff => match char::from_u32(n) { None => Err(TryFromIntToCharError::Reserved), Some(c) => Ok(c), }, _ => Err(TryFromIntToCharError::Overflow) } } } )* }; } impl_int_to_char!(i8, i16, i32, i64, isize, u16, u32, u64, usize); #[test] fn test_int_to_char() { assert_eq!(char::try_from(-1), Err(TryFromIntToCharError::Underflow)); assert_eq!(char::try_from(0x7eu32), Ok('~')); assert_eq!(char::try_from(0xd888), Err(TryFromIntToCharError::Reserved)); assert_eq!(char::try_from(0x10ffff), Ok('\u{10ffff}')); assert_eq!( char::try_from(0x110000), Err(TryFromIntToCharError::Overflow) ); } /// Error which occurs when conversion from an integer to a `char` fails. #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum TryFromIntToCharError { Overflow, Underflow, Reserved, } impl TryFromIntToCharError { fn as_str(self) -> &'static str { match self { TryFromIntToCharError::Overflow => "integer overflow", TryFromIntToCharError::Underflow => "integer underflow", TryFromIntToCharError::Reserved => "reserved code point", } } } impl Display for TryFromIntToCharError { fn fmt(&self, f: &mut Formatter) -> fmt::Result { f.write_str(self.as_str()) } } cfg_if! ( if #[cfg(not(feature="no_std"))] { impl Error for TryFromIntToCharError { fn description(&self) -> &str { self.as_str() } } } ); impl From for TryFromIntToCharError { fn from(other: TryFromIntError) -> TryFromIntToCharError { match other { TryFromIntError::Overflow => TryFromIntToCharError::Overflow, TryFromIntError::Underflow => TryFromIntToCharError::Underflow, } } } impl From for TryFromIntToCharError { fn from(_: Void) -> TryFromIntToCharError { unreachable!() } } try_from-0.3.2/src/int.rs010064400007650000024000000173161337760406400135450ustar0000000000000000// Conversion between machine integers. cfg_if! ( if #[cfg(feature="no_std")] { use core::{u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize}; use core::fmt::{self, Display, Formatter}; use core::mem; } else { use std::{u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize}; use std::error::Error; use std::fmt::{self, Display, Formatter}; use std::mem; } ); use {TryFrom, Void}; /// Error which occurs when conversion from one integer type to another fails. #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum TryFromIntError { Overflow, Underflow, } impl TryFromIntError { fn as_str(self) -> &'static str { match self { TryFromIntError::Overflow => "integer overflow", TryFromIntError::Underflow => "integer underflow", } } } impl Display for TryFromIntError { fn fmt(&self, n: &mut Formatter) -> fmt::Result { n.write_str(self.as_str()) } } cfg_if! ( if #[cfg(not(feature="no_std"))] { impl Error for TryFromIntError { fn description(&self) -> &str { self.as_str() } } } ); macro_rules! impl_infallible { { $($t:ident from $($f:ident),*;)* } => { $($( impl TryFrom<$f> for $t { type Err = Void; fn try_from (n: $f) -> Result<$t, Void> { Ok(n as $t) } } )*)* }; } impl_infallible! { u8 from u8; u16 from u8, u16; u32 from u8, u16, u32; u64 from u8, u16, u32, u64, usize; u128 from u8, u16, u32, u64, u128; usize from u8, u16, u32, usize; i8 from i8; i16 from u8, i8, i16; i32 from u8, u16, i8, i16, i32; i64 from u8, u16, u32, i8, i16, i32, i64, isize; i128 from i8, i16, i32, i64, i128; isize from u8, u16, i8, i16, i32, isize; } #[test] fn test_infallible() { assert_eq!(u64::try_from(usize::MAX), Ok(usize::MAX as u64)); } macro_rules! impl_unsigned_from_unsigned { { $($t:ident from $($f:ident),*;)* } => { $($( impl TryFrom<$f> for $t { type Err = TryFromIntError; fn try_from (n: $f) -> Result<$t, TryFromIntError> { if mem::size_of::<$f>() > mem::size_of::<$t>() && n > $t::MAX as $f { Err(TryFromIntError::Overflow) } else { Ok(n as $t) } } } )*)* }; } impl_unsigned_from_unsigned! { u8 from u16, u32, u64, u128, usize; u16 from u32, u64, u128, usize; u32 from u64, u128, usize; u64 from u128; usize from u64, u128; } #[test] fn test_unsigned_from_unsigned() { assert_eq!(u8::try_from(0xffu16), Ok(0xffu8)); assert_eq!(u8::try_from(0x100u16), Err(TryFromIntError::Overflow)); if cfg!(target_pointer_width = "32") { assert_eq!(u32::try_from(usize::MAX), Ok(u32::MAX)); assert_eq!(usize::try_from(u64::MAX), Err(TryFromIntError::Overflow)); } else if cfg!(target_pointer_width = "64") { assert_eq!(u32::try_from(usize::MAX), Err(TryFromIntError::Overflow)); assert_eq!(usize::try_from(u64::MAX), Ok(usize::MAX)); } } macro_rules! impl_unsigned_from_signed { { $($t:ident from $($f:ident),*;)* } => { $($( impl TryFrom<$f> for $t { type Err = TryFromIntError; fn try_from (n: $f) -> Result<$t, TryFromIntError> { if n < 0 { Err(TryFromIntError::Underflow) } else if mem::size_of::<$f>() > mem::size_of::<$t>() && n > $t::MAX as $f { Err(TryFromIntError::Overflow) } else { Ok(n as $t) } } } )*)* }; } impl_unsigned_from_signed! { u8 from i8, i16, i32, i64, i128, isize; u16 from i8, i16, i32, i64, i128, isize; u32 from i8, i16, i32, i64, i128, isize; u64 from i8, i16, i32, i64, i128, isize; u128 from i8, i16, i32, i64, i128, isize; usize from i8, i16, i32, i64, i128, isize; } #[test] fn test_unsigned_from_signed() { assert_eq!(u8::try_from(0i16), Ok(0u8)); assert_eq!(u8::try_from(-1i16), Err(TryFromIntError::Underflow)); assert_eq!(u8::try_from(256i16), Err(TryFromIntError::Overflow)); assert_eq!(u128::try_from(i32::MAX), Ok(i32::MAX as u128)); assert_eq!(u128::try_from(-1i32), Err(TryFromIntError::Underflow)); if cfg!(target_pointer_width = "32") { assert_eq!(u32::try_from(isize::MAX), Ok(0x7fff_ffffu32)); assert_eq!(usize::try_from(i64::MAX), Err(TryFromIntError::Overflow)); } else if cfg!(target_pointer_width = "64") { assert_eq!(u32::try_from(isize::MAX), Err(TryFromIntError::Overflow)); assert!(usize::try_from(i64::MAX).unwrap() > 0xffff_ffffusize); } } macro_rules! impl_signed_from_unsigned { { $($t:ident from $($f:ident),*;)* } => { $($( impl TryFrom<$f> for $t { type Err = TryFromIntError; fn try_from (n: $f) -> Result<$t, TryFromIntError> { if mem::size_of::<$f>() >= mem::size_of::<$t>() && n > $t::MAX as $f { Err(TryFromIntError::Overflow) } else { Ok(n as $t) } } } )*)* }; } impl_signed_from_unsigned! { i8 from u8, u16, u32, u64, u128, usize; i16 from u16, u32, u64, u128, usize; i32 from u32, u64, u128, usize; i64 from u64, u128, usize; isize from u32, u64, u128, usize; } #[test] fn test_signed_from_unsigned() { assert_eq!(i8::try_from(0x7fu8), Ok(0x7fi8)); assert_eq!(i8::try_from(0x80u8), Err(TryFromIntError::Overflow)); assert_eq!(i64::try_from(i64::MAX as u128), Ok(i64::MAX)); assert_eq!(i64::try_from(u128::MAX), Err(TryFromIntError::Overflow)); if cfg!(target_pointer_width = "32") { assert_eq!(i64::try_from(usize::MAX), Ok(0xffff_ffffi64)); assert_eq!( isize::try_from(0x8000_0000u64), Err(TryFromIntError::Overflow) ); } else if cfg!(target_pointer_width = "64") { assert_eq!(i64::try_from(usize::MAX), Err(TryFromIntError::Overflow)); assert!(isize::try_from(0x8000_0000u64).unwrap() > 0x7fff_ffff); } } macro_rules! impl_signed_from_signed { { $($t:ident from $($f:ident),*;)* } => { $($( impl TryFrom<$f> for $t { type Err = TryFromIntError; fn try_from (n: $f) -> Result<$t, TryFromIntError> { if mem::size_of::<$f>() > mem::size_of::<$t>() { if n > $t::MAX as $f { return Err(TryFromIntError::Overflow); } else if n < $t::MIN as $f { return Err(TryFromIntError::Underflow); } } Ok(n as $t) } } )*)* }; } impl_signed_from_signed! { i8 from i16, i32, i64, i128, isize; i16 from i32, i64, i128, isize; i32 from i64, i128, isize; i64 from i128; isize from i64, i128; } #[test] fn test_signed_from_signed() { assert_eq!(i8::try_from(127i16), Ok(127i8)); assert_eq!(i8::try_from(128i16), Err(TryFromIntError::Overflow)); assert_eq!(i8::try_from(-128i16), Ok(-128i8)); assert_eq!(i8::try_from(-129i16), Err(TryFromIntError::Underflow)); assert_eq!(i64::try_from(i64::MAX as i128), Ok(i64::MAX)); assert_eq!(i64::try_from(i128::MAX), Err(TryFromIntError::Overflow)); if cfg!(target_pointer_width = "32") { assert_eq!(i32::try_from(isize::MAX), Ok(i32::MAX)); assert_eq!(isize::try_from(i64::MAX), Err(TryFromIntError::Overflow)); } else if cfg!(target_pointer_width = "64") { assert_eq!(i32::try_from(isize::MAX), Err(TryFromIntError::Overflow)); assert!(isize::try_from(i64::MAX).unwrap() > 0x7fff_ffffisize); } } try_from-0.3.2/src/lib.rs010075500007650000024000000031121337753646300135200ustar0000000000000000#![cfg_attr(feature = "no_std", no_std)] #[macro_use] extern crate cfg_if; cfg_if! ( if #[cfg(feature="no_std")] { use core::str::FromStr; } else { use std::str::FromStr; } ); mod char; mod int; pub use char::TryFromIntToCharError; pub use int::TryFromIntError; pub trait TryFrom: Sized { type Err; fn try_from(T) -> Result; } pub trait TryInto: Sized { type Err; fn try_into(self) -> Result; } impl TryInto for T where U: TryFrom, { type Err = U::Err; fn try_into(self) -> Result { U::try_from(self) } } impl<'a, T> TryFrom<&'a str> for T where T: FromStr, { type Err = T::Err; fn try_from(string: &'a str) -> Result { T::from_str(string) } } #[cfg(test)] mod tests { use super::*; #[test] fn should_have_try_from_impl_for_from_str() { let result = u32::try_from("3"); assert_eq!(result.unwrap(), 3) } #[test] fn should_have_try_from_impl_for_from_str_that_handles_err() { let result = u32::try_from("hello"); assert_eq!( format!("{}", result.unwrap_err()), "invalid digit found in string" ) } #[test] fn should_have_try_into_impl_for_from_str() { let result: Result = "3".try_into(); assert_eq!(result.unwrap(), 3) } } /// Error type used when conversion is infallible. /// The never type (`!`) will replace this when it is available in stable Rust. #[derive(Debug, Eq, PartialEq)] pub enum Void {} try_from-0.3.2/.cargo_vcs_info.json0000644000000001120000000000000127300ustar00{ "git": { "sha1": "1606a9ae37788360dc422d9fc09c80920e318ddf" } }