I'm trying to write a macro that would turn a number into a byte string literal, similar to how the stringify! macro can turn its argument into a &str.
More concretely, how would I write this:
byte_stringify!(10) -> b"10"
I will be using this to create a large number of const structs, so I can't really rely on calling a method on str.
More ambitiously, I'm actually trying to prepend and append some text before turning the argument into a byte string:
make_arg!(10) -> b"x10y"
Update:
Where did the old bytes! macro go? I think I want:
bytes!(stringify!(10))
You can't; at least, not without writing a compiler plugin, which is far beyond the scope of a simple Stack Overflow response.
There's some basic documentation on the subject in the Compiler Plugins chapter of the Rust Book, though do keep in mind that compiler plugins only work on nightly Rust; they do not work in any stable or beta release, thus also locking any crate that uses them to nightly Rust.
Sorry about that.
Related
Rust code can be debugged using LLDB. The representation of variables used by tools like CodeLLDB, though, is simply a breakdown of the in-memory contents of the variable and does not show any information from the standard Debug trait.
Is there any way using LLDB I can invoke the actual Debug representation of a variable at runtime? This often has a significant amount of useful information which is not clear from a simple memory snapshot.
The "Debug" trait in Rust looks like a pretty close equivalent to the ObjC and Swift object description methods: it provides a to-string method that prints a developer-friendly view of the object. From what I can tell this trait cooperates with the standard formatted printing machinery in Rust.
If that's right, the natural way to give access to the Rust Debug Trait in lldb would be to implement the "Object Description" part of lldb's "Rust LanguageRuntime" and call the print function under the covers. This would be accessed by the po or print-object command in lldb.
Unfortunately, Rust doesn't have a "Rust LanguageRuntime" in lldb or really much of any support currently. The only mentions of Rust in the lldb sources are a recognizer for the Rust mangling scheme and a define that says "other than mangling, pretend Rust is C++". So that isn't a viable option at present.
You could also try calling Rust's print directly in the expression evaluator, but YMMV as calling Rust code in lldb doesn't always work: as it turns out, Rust is not C++...
When to use which type of STRING in eiffel? I saw using READABLE_STRING_GENERAL and having to l_readable_string.out' to convert it to STRING`
READABLE_STRING_GENERAL is an ancestor of all variants of strings: mutable, immutable, 8-bit, 32-bit, so it can be used as a formal argument type when the feature can handle any string variant.
READABLE_STRING_32 is a good choice when the code handles Unicode, and can work with either mutable or immutable versions.
STRING_32 is a mutable Unicode variant. The code can change its value.
STRING is an alias for a string type that can either be STRING_8 or STRING_32. At the time of writing only a few libraries are adapted to handle the mapping of STRING to STRING_32. However, this mapping could become the default in the future to facilitate working with Unicode.
Regardless of the future, I would recommend using ..._STRING_32 to process strings. This way the code directly supports Unicode. The libraries are also updated in this direction. For example, io.put_string_32 can be used to print a Unicode string to the standard output (using the current locale).
Just as a follow-up (I know I am years late in posting anything).
I just had a small question.
Are operations considered literals? Would 2*7, for example, be a literal? Is "hello, " + "world!" a literal?
I know the operands are literals, but the expression is not explicitly 14 or "hello, world!".
The question Is 2+3 considered as a literal?
asks basically what I am asking but most answers weren't even helpful, all they do is break the variable declaration down or talk about what compilers do with them, but I'm not looking for that, so I would like a more in depth explanation.
Thank you
It will depend on the language and the compiler, sorry. But just using the concept that a literal is a kind of token, then no, the result is a compile-time constant, not a token.
In C/C++ 2*7 will be optimised by the compiler to make a new constant but it isn't actually legally defined as a literal, though it can be treated as a compile-time constant.
Concatenating "hello" "world" (note no plus) is actually described as a preprocessing step in c++, so does generate a new literal constant string, but then in original C this didn't work.
But note that in C, a macro will treat the parameter phrase 2+7 as separate tokens, and #define STUPIDMUL3(val) 3 * val for 2+7 will give the answer 13, not 18. If you could find a way to force macros to treat the two halves of the string differently, I think it would.
I would expect an interpreter to take longer to process 2*7 than it would 14 because it might interpret and solve it every time.
I am trying to extract bits of code from an embedded rust example that does not compile. A lot of these old embedded examples don't compile because they use nightly and they quickly become broken and neglected.
let mut buffer : [u8; 2048] = [0;2048];
// some code to fill the buffer here
// say we want to split the buffer at position 300
let (request_buffer, response_buffer) = buffer.split_mut_at(300);
This example uses #![no_std] so there is no standard library to link to and must have compiled at some point so the function split_mut_at must have worked at some point. I am using IntelliJ rust AND Visual Studio Code as the IDE but neither IDE's can point me to the definition of the split_mut_at function. There is a minefield of crates and use statements in the example and there is no clear way to pin-point where some function comes without huge trial and error effort.
btw, split_at_mut can usually be found in std::string::String
Is there a rust command that tells you what crate a function belongs to in your project? It always takes so long to update rust-docs when doing a rust update. Surely that can help!
You're looking for slice::split_at_mut (note the mut at the end). It is listed in the nightly docs here and the stable docs here. It is also indeed available with #![no_std]. It is defined in libcore here.
As a general rule of thumb when a function x from core or std has a mutable and immutable variant, the function requiring a immutable reference is named x and the function requiring a mutable reference is named x_mut.
I am starting out learning Rust macros, but the documentation is somewhat limited. Which is fine — they're an expert feature, I guess. While I can do basic code generation, implementation of traits, and so on, some of the built-in macros seem well beyond that, such as the various print macros, which examine a string literal and use that for code expansion.
I looked at the source for print! and it calls another macro called format_args. Unfortunately this doesn't seem to be built in "pure Rust" the comment just says "compiler built-in."
Is it possible to write something as complex as print! in a pure Rust macro? If so, how would it be done?
I'm actually interested in building a "compile time trie" -- basically recognizing certain fixed strings as "keywords" fixed at compile time. This would be performant (probably) but mostly I'm just interested in code generation.
format_args is implemented in the compiler itself, in the libsyntax_ext crate. The name is registered in the register_builtins function, and the code to process it has its entry point in the expand_format_args function.
Macros that do such detailed syntax processing cannot be defined using the macro_rules! construct. They can be defined with a procedural macro; however, this feature is currently unstable (can only be used with the nightly compiler and is subject to sudden and unannounced changes) and rather sparsely documented.
Rust macros cannot parse string literals, so it's not possible to create a direct Rust equivalent of format_args!.
What you could do is to use a macro to transform the function-call-like syntax into something that represents the variadic argument list in the Rust type system in some way (say, as a heterogeneous single-linked list, or a builder type). This can then be passed to a regular Rust function, along with the format string. But you will not be able to implement compile-time type checking of the format string this way.