Skip to content

Instantly share code, notes, and snippets.

@mmstick
Last active April 21, 2016 17:52
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 mmstick/082d34863ce4c6a30a7fbbdc813b3213 to your computer and use it in GitHub Desktop.
Save mmstick/082d34863ce4c6a30a7fbbdc813b3213 to your computer and use it in GitHub Desktop.
Custom traits for implementing try() for Result and Option types and digits() for usize integers
/// A trait that adds the ability for numbers to find their digit count and to convert them to padded strings.
trait Digits {
/// Counts the number of digits in a number. **Example:** {{0 = 0}, {1 = 1}, {10 = 2}, {100 = 3}}
fn digits(&self) -> usize;
/// Converts a number into a padded String, using `pad` as the character to pad with and `limit` as the size.
fn to_padded_string(&self, pad: char, limit: usize) -> String;
}
impl Digits for usize {
/// Count the number of digits in a usize integer.
fn digits(&self) -> usize {
let mut digits = if *self % 10 == 0 { 1 } else { 0 };
let mut temp = 1;
while temp < *self {
digits += 1;
temp = (temp << 3) + (temp << 1);
}
digits
}
/// Return the usize integer as a padded string.
fn to_padded_string(&self, pad: char, limit: usize) -> String {
if self.digits() < limit {
let mut output = String::with_capacity(limit);
output.push_str(&iter::repeat(pad).take(limit-1).collect::<String>());
output.push_str(&self.to_string());
output
} else {
self.to_string()
}
}
}
trait Try {
type Succ;
/// Unwrap or abort program with an exit status of 1.
fn try(self, message: &[u8], stderr: &mut io::Stderr) -> Self::Succ;
}
trait TryAndIgnore {
type Succ;
/// Print an error message and ignore the error.
fn try_and_ignore(self, message: &[u8], stderr: &mut io::Stderr) -> Self::Succ;
}
impl<T, U: Error> Try for Result<T, U> {
type Succ = T;
/// Unwrap or abort program with an exit status of 1.
fn try(self, message: &[u8], stderr: &mut io::Stderr, ) -> T {
self.unwrap_or_else(|e| {
let mut stderr = stderr.lock();
let _ = stderr.write(b"program-name: ");
let _ = stderr.write(message);
let _ = stderr.write(e.description().as_bytes());
let _ = stderr.write(b"\n");
let _ = stderr.flush();
process::exit(1);
})
}
}
impl <T, U: Error> TryAndIgnore for Result<T, U> {
type Succ = T;
/// Print an error message and ignore the error.
fn try_and_ignore(self, message: &[u8], stderr: &mut io::Stderr, ) -> T {
self.unwrap_or_else(|_| {
let mut stderr = stderr.lock();
let _ = stderr.write(b"program-name: ");
let _ = stderr.write(message);
let _ = stderr.write(b"\n");
let _ = stderr.flush();
process::exit(1);
})
}
}
impl<T> Try for Option<T> {
type Succ = T;
/// Unwrap or abort program with an exit status of 1.
fn try(self, message: &[u8], stderr: &mut io::Stderr) -> T {
self.unwrap_or_else(|| {
let mut stderr = stderr.lock();
let _ = stderr.write(b"program-name: ");
let _ = stderr.write(message);
let _ = stderr.write(b"\n");
let _ = stderr.flush();
process::exit(1);
})
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment