-
-
Save svartalf/b3af107b83c4816bebe900d012dd8a6b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![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