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

Split from_gatt and to_gatt into separate traits and implement for &'static str #289

Merged
merged 5 commits into from
Feb 20, 2025

Conversation

petekubiak
Copy link
Collaborator

The implementation of GattValue for &'_ str was incorrect, and was returning the reference's memory on the stack rather than the slice it was pointing to. Furthermore, there were issues linking lifetimes of references as gatt values to their &[u8] equivalent (see #272 for more details)

This PR splits GattValue into separate traits FromGatt and ToGatt where FromGatt requires that ToGatt is implemented. This allows us to implement to_gatt on &'static str and other static references without having to implement from_gatt, which would potentially be unsafe.

Fixes #272.

@jamessizeland
Copy link
Collaborator

Just a thought, should the trait be IntoGatt rather than ToGatt? I'm not sure which is more idiomatic.

@petekubiak
Copy link
Collaborator Author

petekubiak commented Feb 19, 2025

Just a thought, should the trait be IntoGatt rather than ToGatt? I'm not sure which is more idiomatic.

I wondered this, and then thought that if the trait was called IntoGatt, the function should also be called into_gatt...

EDIT: Turns out Clippy has a good answer:
image

@petekubiak
Copy link
Collaborator Author

/test

@jscatena88
Copy link

In reference to the trait names there is potentially an argument to be made that it should be AsGatt if we think the conversions will always be fairly cheap. To implies that is an expensive/slow conversion: https://rust-lang.github.io/api-guidelines/naming.html#ad-hoc-conversions-follow-as_-to_-into_-conventions-c-conv

This is a nit though so don't feel obligated at all

Comment on lines +173 to +180
impl ToGatt for &'static str {
const MIN_SIZE: usize = 0;
const MAX_SIZE: usize = usize::MAX;

fn to_gatt(&self) -> &[u8] {
self.as_bytes()
}
}
Copy link

@jscatena88 jscatena88 Feb 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this have to be static? I'd imagine almost any use case would have it be static but I wonder if you can get a little extra flexibility by using a generic lifetime. This should work the same for a &'static str I believe while also allowing non-static &strs to be used assuming the borrow checker agrees.

Suggested change
impl ToGatt for &'static str {
const MIN_SIZE: usize = 0;
const MAX_SIZE: usize = usize::MAX;
fn to_gatt(&self) -> &[u8] {
self.as_bytes()
}
}
impl<'a> ToGatt for &'a str {
const MIN_SIZE: usize = 0;
const MAX_SIZE: usize = usize::MAX;
fn to_gatt(&self) -> &'a [u8] {
self.as_bytes()
}
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See the discussion here #272 @jscatena88

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like the complications there were from implementing from_gatt not to_gatt. I'm still somewhat confident that the code I wrote above should work actually. It is passing tests locally on my laptop (except for one test that seems to be expecting connected hardware? gatt_client_server). But either way not a big deal

@jscatena88
Copy link

Overall looks like a great improvement! I don't have time at this exact moment to test on HW or on the project I was working on but I see no reason it wouldn't all work

Copy link
Member

@lulf lulf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for fixing this, looks great!

@lulf lulf merged commit 23cb851 into embassy-rs:main Feb 20, 2025
3 checks passed
@petekubiak
Copy link
Collaborator Author

Just to mention, I'm fully on board with moving to AsGatt instead, I think there's a strong argument there. I'll raise a PR for it.

@petekubiak petekubiak deleted the fix-string-slice-impl-of-gattvalue branch February 20, 2025 15:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Impl of FixedGattValue for &str seems wrong
4 participants