Skip to content

Instantly share code, notes, and snippets.

@elycruz
Created May 5, 2024 05:36
Show Gist options
  • Save elycruz/2c50feb323b5cd8ecc72f23b1516bcee to your computer and use it in GitHub Desktop.
Save elycruz/2c50feb323b5cd8ecc72f23b1516bcee to your computer and use it in GitHub Desktop.
`dyn Fn(T)` Variance/lifetime Issue
use std::fmt::{Display};
use std::borrow::Cow;
/// Represent some scalar values for test.
///
trait InputValue: Copy + Default + Display + PartialEq + PartialOrd {}
impl InputValue for isize {}
impl InputValue for usize {}
impl InputValue for &str {}
// ...
// Set up some types
// ----
type ViolationMessage = String;
type ValidationResult = Result<(), Vec<ViolationMessage>>;
type Validator<T> = dyn Fn(T) -> ValidationResult + Send + Sync;
/// Used for input validation
trait InputConstraints<T>
where T: InputValue {
fn _validate_t_strategy_1(&self, t: T) -> ValidationResult {
println!("Incoming value: {}", t);
Ok(())
}
fn validate(&self, value: Option<T>) -> ValidationResult {
self._validate_t_strategy_1(value.unwrap())
}
}
/// Extends `InputConstraints` in order to be used for validation;
/// Instances expected to be long lived.
struct Input<'a, T>
where T: InputValue
{
// Type that causes the lifetime issue
pub validators: Option<Vec<&'a Validator<T>>>,
}
impl<'a, T> InputConstraints<T> for Input<'a, T>
where T: InputValue {}
/// Faux data model, for validation test
struct SomeModel {
name: String
}
impl SomeModel {
fn validate(&self, rules: &InputRules) -> ValidationResult {
// mimick some lifetime redirection
some_deep_ctx_validate_model_name(rules, self.name.as_str())
}
}
fn some_deep_ctx_validate_model_name(rules: &InputRules, name: &str) -> ValidationResult {
rules.name.validate(Some(name))
}
struct InputRules<'a, 'b> {
name: Input<'a, &'b str>
}
fn app_runtime_ctx(rules: &InputRules, data: String) {
let model = SomeModel {
name: data,
};
model.validate(&rules);
}
fn main() {
let rule: Input<&str> = Input {
validators: None
};
let rules = InputRules {
name: rule,
};
app_runtime_ctx(&rules, "Hello".to_string())
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment