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

how to support uwrite! for CStr ? #33

Open
mutantbob opened this issue Feb 2, 2022 · 1 comment
Open

how to support uwrite! for CStr ? #33

mutantbob opened this issue Feb 2, 2022 · 1 comment

Comments

@mutantbob
Copy link

Working in the Rust/Arduino environment I find myself occasionally dealing with C-style (NUL-terminated) strings when I'm interacting with preexisting C libraries.

While I would like to be able to write

use cstr_core::cstr;
    let server_name = cstr!("www.purplefrog.com");
    let _ = uwriteln!(&mut serial, "connecting to {}...", server_name);

I get

error[E0277]: the trait bound `CStr: uDisplay` is not satisfied
   --> src/web_client.rs:89:13
    |
89  |     let _ = uwriteln!(&mut serial, "connecting to {}...", server_name);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `uDisplay` is not implemented for `CStr`
    | 
   ::: /home/thoth/.cargo/registry/src/github.com-1ecc6299db9ec823/ufmt-0.1.0/src/lib.rs:268:12
    |
268 |         W: uWrite + ?Sized;
    |            ------ required by this bound in `ufmt::uDisplay::fmt`
    |
    = note: required because of the requirements on the impl of `uDisplay` for `&CStr`
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

So instead I have to

  let _ = uwrite!(&mut serial, "connecting to ");
    for ch in server_name.to_bytes() {
        let _ = serial.write_byte(*ch);
    }
    let _ = uwriteln!(&mut serial, "...");

I am not sure if the cstr_core crate should impl uDisplay for &CStr or if ufmt should do it, or maybe use server_name.to_bytes() to get a &[u8] and have ufmt impl uDisplay for &[u8]

@Cryptjar
Copy link

I don't think a impl uDisplay for &CStr would be reasonable, because CStr has no UTF-8 guarantee, and it is not obvious how to handle a non-UTF-8 CStr (returning an error vs lossy conversion). I think this can be better handled in the user code, where more knowledge is available. Either by using the fallible to_str or the allocating to_string_lossy methods on CStr, e.g.:

use cstr_core::cstr;
let server_name = cstr!("www.purplefrog.com");

// If you expect UTF-8:
let _ = uwriteln!(&mut serial, "connecting to {}...", server_name.to_str().unwrap());

// Or, if it might contain other bytes:
let _ = uwriteln!(&mut serial, "connecting to {}...", server_name.to_string_lossy());

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

No branches or pull requests

2 participants