Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Consider replacing relying on DerefMut with traits #26

Closed
nicopap opened this issue Jul 11, 2023 · 1 comment
Closed

Consider replacing relying on DerefMut with traits #26

nicopap opened this issue Jul 11, 2023 · 1 comment
Labels
C-dsl relates to the cuicui_dsl crate specifically T-code quality How to organize code

Comments

@nicopap
Copy link
Owner

nicopap commented Jul 11, 2023

DerefMut is prone to footguns, it's dangerous to push people to use it. The way we use it is also not a primary use-case as a rust language feature, so we are likely to create poor rust compilation error messages.

So maybe we should swap to traits for this

How would it look like?

So, the idea is to:

For each Dsl, implement methods only as members of a trait:

pub struct MyDsl<T: DslBundle = ()> {
  inner: T,
  zoobi: Zoob,
  bashoung: Bob,
}
pub trait MyDslTrait {
  type Inner;
  fn from_my_dsl(&mut self) -> &mut MyDsl<Self::Inner>;
  
  fn zoobi(&mut self, zoobi: Zoobi) { self.from_my_dsl().zoobi = zoobi; }
  // etc. all methods call `from_my_dsl` and have such default implementation.
}
impl<T:DslBundle> MyDslTrait for MyDsl<T> {
  type Inner = T;
  fn from_my_dsl(&mut self) -> &mut Self { self }
  // The rest is already implemented by default.
}

If we make a macro to derive DslBundle, the very same macro should be able to create and export such a trait.

Now, we can also implement foreign DSLs with this (imagining a ForeignDsl struct and a ForeignDslTrait following the same pattern):

impl<T: ForeignDslTrait> ForeignDslTrait for MyDsl<T> {
  type Inner = T::Inner;
  fn from_foreign_dsl(&mut self) -> &mut ForeignDsl<T::Inner> { &mut self.inner }
}

And now we are back to providing access to methods across all dsls combined into one type.

However, the downside here is that we need to explicitly import all the relevant traits and add those nosiy impl blocks (though they are relatively small)

Ideally, we get rid of the boilerplate with a macro, the downside is that now we are relying on macros for a lot more than before.

@nicopap nicopap added T-code quality How to organize code C-dsl relates to the cuicui_dsl crate specifically labels Jul 11, 2023
@nicopap
Copy link
Owner Author

nicopap commented Aug 20, 2023

I don't think this is a viable option.

@nicopap nicopap closed this as not planned Won't fix, can't repro, duplicate, stale Aug 20, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-dsl relates to the cuicui_dsl crate specifically T-code quality How to organize code
Projects
None yet
Development

No branches or pull requests

1 participant