Closed mutantbob closed 2 years ago
I think it would be helpful to understand why this would be needed. What's the use case for impl uWrite
? I personally don't use ufmt and don't have any need for it. Is there a purpose that it should be pulled into this library, or can it be kept external?
I use uWrite to construct HTTP PUT requests. I also use it to transmit sensor readings. I can understand if uwrite is gated behind a feature flag. I added StackAndSocket
because I wanted the function with_socket()
, although I suspect that method could be added using a custom trait . I'll have to experiment with that.
Wouldn't you be better suited to write those ufmt objects into some intermediary buffer before sending them for transmission to the stack?
E.g.
let mut buffer = heapless::String::new();
uwrite!(&mut buffer, "my_http_format_string", my_http_data).unwrap();
tcp_stack.send(tcp_sock, buffer.as_slice()).unwrap()
I don't see why the network stack itself has to be some type of writable stream outside of the potential desire to avoid buffering?
I tried your example:
let mut x = embedded_nal::heapless::String::new();
uwrite!(&mut x, "bacon {}", 42);
I get the following error
error[E0599]: no method named `do_as_formatter` found for mutable reference `&mut embedded_nal::heapless::String<{_: usize}>` in the current scope
--> src/main.rs:585:5
|
585 | uwrite!(&mut x, "bacon {}", 42);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ method not found in `&mut embedded_nal::heapless::String<{_: usize}>`
|
::: /home/thoth/.cargo/git/checkouts/heapless-c15edde3bc74f47c/8460024/src/string.rs:8:1
|
8 | pub struct String<const N: usize> {
| ---------------------------------
| |
| doesn't satisfy `_: UnstableDoAsFormatter`
| doesn't satisfy `embedded_nal::heapless::String<{_: usize}>: uWrite`
|
= note: the method `do_as_formatter` exists but the following trait bounds were not satisfied:
`embedded_nal::heapless::String<{_: usize}>: uWrite`
which is required by `embedded_nal::heapless::String<{_: usize}>: UnstableDoAsFormatter`
`&mut embedded_nal::heapless::String<{_: usize}>: uWrite`
which is required by `&mut embedded_nal::heapless::String<{_: usize}>: UnstableDoAsFormatter`
`str: uWrite`
which is required by `str: UnstableDoAsFormatter`
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
It turns out that the custom trait is a workable solution without modifying embedded-nal
. https://github.com/mutantbob/embedded-nal-plus/blob/master/src/lib.rs
Using a custom trait will break any kind of cross-compatibility with existing embedded-nal libraries - I would not recommend going that route. I think there are means to work around this without a custom trait and without a custom NAL.
I'm interested in seeing an example of an existing embedded-nal library that would be incompatible with how I designed the custom trait. If anyone can construct one, it would enhance my understanding of Rust.
I agree with @ryan-summers and do not think embedded-nal
would be the place to provide implementations for ufmt
traits.
IIUC there is nothing in ufmt
that embedded-nal
would inherently benefit from and I would keep the rather short adapter code outside of this crate as to avoid non-essential dependencies.
If you disagree, you are welcome to provide a compelling use case and reopen this issue. Closing.
I was refactoring some code to use
embedded-nal
instead of a custom driver and found that embedded-nal does not have any implementation ofufmt::uWrite
.So I created a
struct StackAndSocket
which combines mutable references to theTcpClientStack
andTcpSocket
so that it canimpl uWrite
.https://github.com/mutantbob/embedded-nal/commit/e4a65f48558c433f09ba0853a2d7a0f06a8be294
It is not meant to exist for a long time; you just create it for a quick burst of activity, and then drop it. I use it like this:
I suspect this idea has overlap with https://github.com/rust-embedded-community/embedded-nal/issues/53 ,