Skip to content

Instantly share code, notes, and snippets.

@towry
Last active July 19, 2024 06:19
Show Gist options
  • Save towry/ad7280a6b16e63530d91ac2c1397a944 to your computer and use it in GitHub Desktop.
Save towry/ad7280a6b16e63530d91ac2c1397a944 to your computer and use it in GitHub Desktop.
#[derive(Debug)]
enum AnyValue {
String(String),
Number(i64),
}
// let a: &'str = convert(&value)
// let b: i64 = convert(&value)
fn convert<'a, T: ConvertFromValue<'a> + 'static>(value: &AnyValue) -> Option<T> {
T::convert_from_value(value)
}
trait ConvertFromValue<'a>: Sized {
fn convert_from_value(value: &AnyValue) -> Option<Self>;
}
impl ConvertFromValue<'_> for String {
fn convert_from_value(value: &AnyValue) -> Option<Self> {
match value {
AnyValue::String(v) => Some(v.clone()),
_ => None,
}
}
}
struct ArgCallback {
f: Box<dyn Fn(&AnyValue)->AnyValue>
}
impl ArgCallback {
fn new<'a, F, Arg>(cb: F) -> Self where F: CallbackTrait<'a, Arg> + 'static, Arg: ConvertFromValue<'a> {
ArgCallback {
f: Box::new(move |value: &AnyValue| -> AnyValue {
cb.invoke(Arg::convert_from_value(&value).unwrap())
})
}
}
fn invoke(self, value: &AnyValue) -> AnyValue {
(self.f)(value)
}
}
trait CallbackTrait<'a, Arg> where Arg: ConvertFromValue<'a> {
fn invoke(&self, arg: Arg) -> AnyValue;
}
// let sqaure = ArgCallback::new(|v| AnyValue::Number(v * 2))
// sqaure.invoke(23)
fn main() {
let value = AnyValue::String("23".to_owned());
let strvalue = convert::<String>(&value);
println!("{:?}", strvalue);
}
#[derive(Debug)]
enum AnyValue {
String(String),
Number(i64),
}
// let a: &'str = convert(&value)
// let b: i64 = convert(&value)
fn convert<'a, T: ConvertFromValue<'a> + 'static>(value: &AnyValue) -> Option<T> {
T::convert_from_value(value)
}
trait ConvertFromValue<'a>: Sized {
fn convert_from_value(value: &AnyValue) -> Option<Self>;
}
impl ConvertFromValue<'_> for String {
fn convert_from_value(value: &AnyValue) -> Option<Self> {
match value {
AnyValue::String(v) => Some(v.clone()),
_ => None,
}
}
}
struct ArgCallback<'l> {
f: Box<dyn Fn(&AnyValue)->AnyValue + 'l>
}
impl<'l> ArgCallback<'l> {
fn new<'a, F, Arg>(cb: F) -> Self where F: CallbackTrait<'a, Arg> + 'l, Arg: ConvertFromValue<'a> {
ArgCallback {
f: Box::new(move |value: &AnyValue| -> AnyValue {
cb.invoke(Arg::convert_from_value(&value).unwrap())
})
}
}
fn invoke(self, value: &AnyValue) -> AnyValue {
(self.f)(value)
}
}
trait CallbackTrait<'a, Arg> where Arg: ConvertFromValue<'a> {
fn invoke(&self, arg: Arg) -> AnyValue;
}
// let sqaure = ArgCallback::new(|v| AnyValue::Number(v * 2))
// sqaure.invoke(23)
fn main() {
let value = AnyValue::String("23".to_owned());
let strvalue = convert::<String>(&value);
println!("{:?}", strvalue);
}
#[derive(Debug)]
enum AnyValue {
String(String),
Number(i64),
}
// let a: &'str = convert(&value)
// let b: i64 = convert(&value)
fn convert<'a, T: ConvertFromValue<'a> + 'static>(value: &AnyValue) -> Option<T> {
T::convert_from_value(value)
}
trait ConvertFromValue<'a>: Sized {
fn convert_from_value(value: &AnyValue) -> Option<Self>;
}
impl ConvertFromValue<'_> for String {
fn convert_from_value(value: &AnyValue) -> Option<Self> {
match value {
AnyValue::String(v) => Some(v.clone()),
_ => None,
}
}
}
impl ConvertFromValue<'_> for i64 {
fn convert_from_value(value: &AnyValue) -> Option<Self> {
match value {
AnyValue::Number(x) => Some(x.clone()),
_ => None,
}
}
}
struct ArgCallback<'l> {
f: Box<dyn Fn(&AnyValue) -> AnyValue + 'l>,
}
impl<'l> ArgCallback<'l> {
fn new<'a, F, Arg>(cb: F) -> Self
where
F: CallbackTrait<'a, Arg> + 'l,
Arg: ConvertFromValue<'a>,
{
ArgCallback {
f: Box::new(move |value: &AnyValue| -> AnyValue {
cb.invoke(Arg::convert_from_value(&value).unwrap())
}),
}
}
fn invoke(self, value: &AnyValue) -> AnyValue {
(self.f)(value)
}
}
trait CallbackTrait<'a, Arg>
where
Arg: ConvertFromValue<'a>,
{
fn invoke(&self, arg: Arg) -> AnyValue;
}
impl<'a, Arg, F> CallbackTrait<'a, Arg> for F
where
F: Fn(Arg) -> AnyValue,
Arg: ConvertFromValue<'a>,
{
fn invoke(&self, arg: Arg) -> AnyValue {
(self)(arg)
}
}
// let sqaure = ArgCallback::new(|v| AnyValue::Number(v * 2))
// sqaure.invoke(23)
fn main() {
// let value = AnyValue::String("23".to_owned());
let sqaure = ArgCallback::new(|x: i64| AnyValue::Number(x * 2));
println!("{:?}", sqaure.invoke(&AnyValue::Number(2)));
let join_string = ArgCallback::new(|x: String| AnyValue::String(x + " World!"));
println!(
"{:?}",
join_string.invoke(&AnyValue::String("Hello".to_owned()))
);
}
#[derive(Debug)]
enum AnyValue {
String(String),
Number(i64),
}
// let a: &'str = convert(&value)
// let b: i64 = convert(&value)
fn convert<'a, T: ConvertFromValue<'a> + 'static>(value: &'a AnyValue) -> Option<T> {
T::convert_from_value(value)
}
trait ConvertFromValue<'a>: Sized {
fn convert_from_value(value: &'a AnyValue) -> Option<Self>;
}
impl ConvertFromValue<'_> for String {
fn convert_from_value(value: &AnyValue) -> Option<Self> {
match value {
AnyValue::String(v) => Some(v.clone()),
_ => None,
}
}
}
impl ConvertFromValue<'_> for i64 {
fn convert_from_value(value: &AnyValue) -> Option<Self> {
match value {
AnyValue::Number(x) => Some(x.clone()),
_ => None,
}
}
}
impl<'a> ConvertFromValue<'a> for &'a str {
fn convert_from_value(value: &'a AnyValue) -> Option<Self> {
match value {
AnyValue::String(v) => Some(v),
_ => None,
}
}
}
struct ArgCallback<'l> {
f: Box<dyn Fn(&'l AnyValue) -> AnyValue + 'l>,
}
impl<'l> ArgCallback<'l> {
fn new<'a, F, Arg>(cb: F) -> Self
where
'l: 'a,
F: CallbackTrait<'a, Arg> + 'l,
Arg: ConvertFromValue<'a>,
{
// 这里,我们需要将这个闭包 连同 闭包需要的变量一起捕获,然后被
// ArgCallback 所拥有,所以,捕获的数据的生命周期需要比 ArgCallback 的数据长久。
// 即比 `'l` 长久。
// 所以,cb 要比 l 长久,cb所持有或者引用的数据需要比 l 长久,其中包括 cb 的生命周期 a。
ArgCallback {
f: Box::new(move |value: &AnyValue| -> AnyValue {
cb.invoke(Arg::convert_from_value(&value).unwrap())
}),
}
}
// 因为 ArgCallback 需要生存至少 l 的生命周期,那么它引用的数据或者拥有的数据
// 必须要至少生存这么长时间。那么传递给它的方法的引用也要和它self的生命周期的关系
// 有正确的语义(方法invoke是ArgCallback上的一个属性,属于ArgCallback)。
// 如果
// ArgCallback有多个生命周期的话,那么最短的那个生命周期明显是ArgCallback至少要生存的周期。
fn invoke<'c: 'l>(self, value: &'c AnyValue) -> AnyValue {
(self.f)(value)
}
}
trait CallbackTrait<'a, Arg>
where
Arg: ConvertFromValue<'a>,
{
fn invoke(&self, arg: Arg) -> AnyValue;
}
impl<'a, Arg, F> CallbackTrait<'a, Arg> for F
where
F: Fn(Arg) -> AnyValue,
Arg: ConvertFromValue<'a>,
{
fn invoke(&self, arg: Arg) -> AnyValue {
(self)(arg)
}
}
// let sqaure = ArgCallback::new(|v| AnyValue::Number(v * 2))
// sqaure.invoke(23)
fn main() {
// let value = AnyValue::String("23".to_owned());
let sqaure = ArgCallback::new(|x: i64| AnyValue::Number(x * 2));
println!("{:?}", sqaure.invoke(&AnyValue::Number(2)));
let join_string = ArgCallback::new(|x: String| AnyValue::String(x + " World!"));
println!(
"{:?}",
join_string.invoke(&AnyValue::String("Hello".to_owned()))
);
}
#[test]
fn test_me() {
assert_eq!(2, 2);
}
#[derive(Debug)]
enum AnyValue {
String(String),
Number(i64),
}
// let a: &'str = convert(&value)
// let b: i64 = convert(&value)
#[allow(dead_code)]
fn convert<'a, T: ConvertFromValue<'a> + 'static>(value: &'a AnyValue) -> Option<T> {
T::convert_from_value(value)
}
trait ConvertFromValue<'a>: Sized {
fn convert_from_value(value: &'a AnyValue) -> Option<Self>;
}
impl ConvertFromValue<'_> for String {
fn convert_from_value(value: &AnyValue) -> Option<Self> {
match value {
AnyValue::String(v) => Some(v.clone()),
_ => None,
}
}
}
impl ConvertFromValue<'_> for i64 {
fn convert_from_value(value: &AnyValue) -> Option<Self> {
match value {
AnyValue::Number(x) => Some(*x),
_ => None,
}
}
}
impl<'a> ConvertFromValue<'a> for &'a str {
fn convert_from_value(value: &'a AnyValue) -> Option<Self> {
match value {
AnyValue::String(v) => Some(v),
_ => None,
}
}
}
struct ArgCallback<'l> {
f: Box<dyn Fn(&'l AnyValue) -> Option<AnyValue> + 'l>,
}
impl<'l> ArgCallback<'l> {
fn new<'a, F, Arg>(cb: F) -> Self
where
'l: 'a,
F: CallbackTrait<'a, Arg> + 'l,
Arg: ConvertFromValue<'a>,
{
// 这里,我们需要将这个闭包 连同 闭包需要的变量一起捕获,然后被
// ArgCallback 所拥有,所以,捕获的数据的生命周期需要比 ArgCallback 的数据长久。
// 即比 `'l` 长久。
// 所以,cb 要比 l 长久,cb所持有或者引用的数据需要比 l 长久,其中包括 cb 的生命周期 a。
ArgCallback {
f: Box::new(move |value: &AnyValue| -> Option<AnyValue> {
let arg = Arg::convert_from_value(value)?;
cb.invoke(arg)
}),
}
}
// 因为 ArgCallback 需要生存至少 l 的生命周期,那么它引用的数据或者拥有的数据
// 必须要至少生存这么长时间。那么传递给它的方法的引用也要和它self的生命周期的关系
// 有正确的语义(方法invoke是ArgCallback上的一个属性,属于ArgCallback)。
// 如果
// ArgCallback有多个生命周期的话,那么最短的那个生命周期明显是ArgCallback至少要生存的周期。
fn invoke<'c: 'l>(self, value: &'c AnyValue) -> Option<AnyValue> {
(self.f)(value)
}
}
trait CallbackTrait<'a, Arg>
where
Arg: ConvertFromValue<'a>,
{
fn invoke(&self, arg: Arg) -> Option<AnyValue>;
}
impl<'a, Arg, F> CallbackTrait<'a, Arg> for F
where
F: Fn(Arg) -> Option<AnyValue>,
Arg: ConvertFromValue<'a>,
{
fn invoke(&self, arg: Arg) -> Option<AnyValue> {
(self)(arg)
}
}
// let sqaure = ArgCallback::new(|v| AnyValue::Number(v * 2))
// sqaure.invoke(23)
fn main() {
// let value = AnyValue::String("23".to_owned());
let sqaure = ArgCallback::new(|x: i64| Some(AnyValue::Number(x * 2)));
println!("{:?}", sqaure.invoke(&AnyValue::Number(2)));
let join_string = ArgCallback::new(|x: String| Some(AnyValue::String(x + " World!")));
println!(
"{:?}",
join_string.invoke(&AnyValue::String("Hello".to_owned()))
);
let join_strs = ArgCallback::new(|x: &str| Some(AnyValue::String(x.to_string() + " ok")));
println!("{:?}", join_strs.invoke(&AnyValue::String("Hi".to_owned())));
let test_none = ArgCallback::new(|x: &str| Some(AnyValue::String(x.to_string() + " ok")));
println!("{:?}", test_none.invoke(&AnyValue::Number(33)));
}
#[test]
fn test_me() {
assert_eq!(2, 2);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment