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

add format macro implementation #369

Merged
merged 5 commits into from
Nov 20, 2023
Merged

Conversation

ede1998
Copy link
Contributor

@ede1998 ede1998 commented May 30, 2023

Motivation:
If you want to create a formatted heapless::String at the moment, it is necessary to create a mutable string and modify it:

let mut string = heapless::String::<10>::new();
write!(&mut string, "{:>3}cm", height).unwrap();

It's a bit nicer to have a format! macro that constructs the String in-place without requiring an intermediate step, just as Rust's standard library offers.

let string = format!(10, "{:>3}cm", height);

Copy link
Member

@Dirbaio Dirbaio 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 the PR!

Could you change it to return a Result instead of panicking if it runs out of space? We should avoid implicit panics as much as possible. It's true std's format! panics on fmt errors, but these are super rare. Running out of space is more likely.

Also I wonder if we could let rust infer the string length instead of having to specify it manually.

Thanks!

@Dirbaio Dirbaio marked this pull request as draft October 31, 2023 00:07
@ede1998
Copy link
Contributor Author

ede1998 commented Oct 31, 2023

Sure thing.

Regarding inferring the capacity: This should be possible. However I'm not sure this is a good idea. If you want to bind the string to a new variable, you now have to specify the entire type just to be allowed to add the capacity, which adds quite a bit of noise:

let foo: helpless::String<10> = format!(...);

It pretty much comes down to what is the more common usage pattern.
If you use the macro to initialize a field of an existing struct (-> type and capacity already fixed), it makes it nicer as you don't have to repeat the capacity in the macro.

Or I could experiment with making it optional in the macro, so that the first parameter is a string -> infer, and if it's a number -> use capacity. That might actually be a more elegant solution.

@Dirbaio
Copy link
Member

Dirbaio commented Oct 31, 2023

yeah that's true. Supporting both syntaxes sounds good to me! like format!("foo {}", foo) or format!(32, "foo {}", foo)

@birkenfeld
Copy link
Contributor

helpless::String

That's another crate still ;)

@ede1998
Copy link
Contributor Author

ede1998 commented Nov 1, 2023

Seems like my phone's autocorrect was in a funny mood.

I updated the PR. The macro now returns a Result<String<N>, core::fmt::Error>.

The inferred capacity unfortunately did not work as planned. I had to use a semicolon as separator instead.

struct Inferred {
  name: String<10>,
}

let inf = Inferred {
  name: format!("Hello {}", "World")?,
};

// Notice semicolon here: otherwise Rust would pick up 10 as the format string and fail.
let explicit = format!(10; "Foo {}", "bar")?;

Hope this is ok too.

@ede1998 ede1998 marked this pull request as ready for review November 1, 2023 19:45
@ede1998 ede1998 requested a review from Dirbaio November 1, 2023 19:45
Dirbaio
Dirbaio previously approved these changes Nov 20, 2023
Copy link
Member

@Dirbaio Dirbaio left a comment

Choose a reason for hiding this comment

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

looking great! Thanks for the PR

@Dirbaio
Copy link
Member

Dirbaio commented Nov 20, 2023

did a small fix, instead of making mod string public which affects the public API, it's nicer to make a "hidden" mod _export that's explicitly unstable for these.

@Dirbaio Dirbaio added this pull request to the merge queue Nov 20, 2023
Merged via the queue into rust-embedded:main with commit 7cd2625 Nov 20, 2023
22 checks passed
@ede1998
Copy link
Contributor Author

ede1998 commented Nov 20, 2023

Oh, yeah that's much nicer. I figured there was only String in the module so it wouldn't be a problem but you're way is better! Thanks for merging!

@Dirbaio Dirbaio mentioned this pull request Jan 1, 2024
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.

3 participants