Skip to content

Instantly share code, notes, and snippets.

@svartalf

svartalf/main.rs Secret

Created December 29, 2016 09:32
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 svartalf/b3af107b83c4816bebe900d012dd8a6b to your computer and use it in GitHub Desktop.
Save svartalf/b3af107b83c4816bebe900d012dd8a6b to your computer and use it in GitHub Desktop.
#![feature(try_from)]
use std::ops::Fn;
use std::boxed::Box;
use std::convert::TryFrom;
#[derive(Debug)]
struct ConversionError;
// Basic struct (internal implementation is skipped) from my library
struct Basic;
// Extended structs which are will be defined out of library scope by end users
struct ExtendedOne(Basic);
struct ExtendedTwo(Basic);
impl TryFrom<Basic> for ExtendedOne {
type Err = ConversionError;
fn try_from(val: Basic) -> Result<Self, Self::Err> {
Ok(ExtendedOne(val)) // As for example, we're assume that conversion is always pass
}
}
impl TryFrom<Basic> for ExtendedTwo {
type Err = ConversionError;
fn try_from(val: Basic) -> Result<Self, Self::Err> {
Ok(ExtendedTwo(val))
}
}
// Call each user-defined handler with a converted value, based on the handler accept type
fn process<F, T>(func: F, basic_value: Basic) -> Result<(), T::Err> where F: Fn(&T), T: TryFrom<Basic> {
let inherited = T::try_from(basic_value)?;
(func)(&inherited);
Ok(())
}
// Processing handlers are created by library end users and passed into library
// As for example, I pretend that Vec<Box<Fn(..)>> is a part of that imaginary library
fn handler_one(val: &ExtendedOne) { unimplemented!() }
fn handler_two(val: &ExtendedTwo) { unimplemented!() }
fn main() {
// So, this one vec is stored somewhere in the library structs.
let handlers: Vec<Box<Fn(&TryFrom<Basic, Err=ConversionError>)>> = vec![];
// User will add handlers into library "processor"
handlers.push(Box::new(handler_one));
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::convert::TryFrom` cannot be made into an object
handlers.push(Box::new(handler_two));
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::convert::TryFrom` cannot be made into an object
// And somewhere later library will call each of them and pass basic value into each of them.
for handler in handlers {
let basic_value = Basic{};
process(handler, basic_value);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment