1

I'm looking for ways to declare String constants in Rust by concatenating chars.

What I would like to achieve is something like this:

{ Pascal Code }
const ESC = #27;
const RESET_PRINTER = ESC + '@';

Here's where I ended for now after few hours of research:

const ESC: char  = '\u{001b}';

const RESET_PRINTER_ARR: [char; 2] = [ESC, '@'];
const RESET_PRINTER_STR: &str = "\u{001b}@"; // ESC + '@' ?

fn cde_str(cde: &[char], len: usize) -> String {
    let mut s = String::from("");
    for i in 0..len {
        s.push(cde[i]);
    }
    s
}

fn main() {
  let r1 = cde_str(&RESET_PRINTER_ARR, RESET_PRINTER_ARR.len()); 
  println!("{}", r1);
  
  let r2 = String::from(RESET_PRINTER_STR); 
  println!("{}", r2);
}

Playground link

Edit

Per @e-net4-stays-away-from-meta suggestion a String can easily be created from [char] by using String::from_iter() :

use std::iter::FromIterator;

const ESC: char = '\u{001b}';
const RESET_PRINTER_ARR: [char; 2] = [ESC, '@'];

fn main() {
  let r0 = String::from_iter(&RESET_PRINTER_ARR);
  println!("{}", r0);
}
7
  • 2
    The same principle of this question may apply: create an iterator of chars, then collect it. Commented Aug 12, 2020 at 13:55
  • 2
    I can't really find the question in this post. Could you please be more explicit? Would you like to evaluate the constants at compile time? Commented Aug 12, 2020 at 14:17
  • 1
    You can also iterate &[char] without passing its size. Just for c in cde {...} or even better cde.into_iter().collect() Commented Aug 12, 2020 at 14:19
  • @SvenMarnach it's exactly that. The goal was to reuse a const char to make a const String , so evaluate a char concatenation for a const. To solve this problem, i use an array and I "collect" it in a String when I need. Commented Aug 12, 2020 at 14:30
  • @aniki02 There is no such thing as a const String in Rust, since you can't allocate memory on the heap when creating a constant. Would a &str work as well for you? Would a lazily initialized static String fit the bill? Commented Aug 12, 2020 at 14:32

1 Answer 1

2

It looks like these are escape sequences to send to a printer, and that kind of printer probably does not naturally work in Unicode. I would make them a byte string.

To me the natural way to write it in Rust is just like this:

const RESET_PRINTER: &[u8] = b"\x1b@";

// other examples
const TERM_BOLD: &[u8] = b"\x1b[1m";
const TERM_UNDERLINE: &[u8] = b"\x1b[4m";

If you're going to generate very many of them, or they are very long, you can potentially write a macro that produces the byte string literals.

But, I would be inclined not to do the macro unless it's clearly needed: within a single crate, simple straight-line code that's a bit repetitive is often more maintainable than something that requires a reader to think about how the macro works.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.