Skip to content

add format macro implementation#369

Merged
Dirbaio merged 5 commits into
rust-embedded:mainfrom
ede1998:format-macro
Nov 20, 2023
Merged

add format macro implementation#369
Dirbaio merged 5 commits into
rust-embedded:mainfrom
ede1998:format-macro

Conversation

@ede1998

@ede1998 ede1998 commented May 30, 2023

Copy link
Copy Markdown
Contributor

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);

@Dirbaio Dirbaio left a comment

Copy link
Copy Markdown
Member

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

ede1998 commented Oct 31, 2023

Copy link
Copy Markdown
Contributor Author

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

Dirbaio commented Oct 31, 2023

Copy link
Copy Markdown
Member

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

@birkenfeld

Copy link
Copy Markdown
Contributor
helpless::String

That's another crate still ;)

@ede1998

ede1998 commented Nov 1, 2023

Copy link
Copy Markdown
Contributor Author

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

@Dirbaio Dirbaio left a comment

Copy link
Copy Markdown
Member

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 Dirbaio enabled auto-merge November 20, 2023 01:52
@Dirbaio

Dirbaio commented Nov 20, 2023

Copy link
Copy Markdown
Member

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 enabled auto-merge November 20, 2023 02:03
@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
@ede1998

ede1998 commented Nov 20, 2023

Copy link
Copy Markdown
Contributor Author

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