Skip to content

Instantly share code, notes, and snippets.

@felipesere
Created September 20, 2021 07:33
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 felipesere/b135230c5ea053f5df5a40cb31cf6e34 to your computer and use it in GitHub Desktop.
Save felipesere/b135230c5ea053f5df5a40cb31cf6e34 to your computer and use it in GitHub Desktop.
Show how I want to track homogenous resources in a provider but still return a specific type so users can still interact with it - even if read-only.
pub struct AwsProvider(Inner);
struct Inner {
creds: Credentials,
region: String,
tracked_resources: RwLock<Vec<Box<dyn Resource<Aws>>>>,
}
// TODO: it would be nice if this could magically put the
// reosurce on the heap (Arc<Box<...>>) and then return
// something like Arc<Box<T>>, assuming `track<T>`
pub fn track(&mut self, resource: Box<dyn Resource<Aws>>) {
self.0.tracked_resources.write().unwrap().push(resource);
}
// -----------------------------------------------------------
// different file...
// -----------------------------------------------------------
// This is the end of a "builder" that will stash away the resource for later usage:
pub fn build(mut self) -> Option<Arc<Box<Bucket>>> {
let bucket = Bucket { Bucket
name: self.name,
acl: self.acl,
website: self.website,
tags: self.tags,
};
// TODO: this is annoying!
// receive a Arc<Box<Bucket>> in return.
// `track(...)` needs to work with `dyn Resource<C: Cloud>` though.
let to_be_stashed_away: Box<dyn Resource<Aws>> = Box::new(bucket.clone());
self.provider.track(to_be_stashed_away);
Some(Arc::new(Box::new(bucket)))
}
}
@felipesere
Copy link
Author

I have left out the aysnc part from async_trait thinking it might have something to do with it but no 😢

// #[async_trait]
pub trait Resource<C: Cloud>: 'static + std::fmt::Debug + Send + Sync {
   /* async */ fn create(&self, provider: &<C as Cloud>::Provider) -> Result<RealState, String>; // Come up with a better error story
      fn as_dyn_any(&self) -> &(dyn Any + '_) {
        &self
      }
}

And the error is:

error[E0477]: the type `&Self` does not fulfill the required lifetime
  --> luminary/src/lib.rs:34:9
   |
34 |         &self
   |         ^^^^^
   |
   = note: type must satisfy the static lifetime

error[E0759]: `self` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
  --> luminary/src/lib.rs:34:9
   |
33 |     fn as_dyn_any(&self) -> &(dyn Any + '_) {
   |                   ----- this data with an anonymous lifetime `'_`...
34 |         &self
   |         ^^^^^ ...is captured and required to live as long as `'static` here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment