How to read an integer from a buffer in Rust 1.0? - io

The API for reading scalar values seems to have been removed from the Cursor and Reader io traits. Is there a standard library replacement for these or do I have to write my own?
For example, it used to be possible to write:
let magic = try!(reader.read_be_u16());

This functionality is not in the standard library any more, but there are other libraries providing it.
byteorder is a popular one.

Related

Can Rust code compile without the standard library?

I'm currently in the progress of learning Rust. I'm mainly using The Rust Programming Language book and this nice reference which relates Rust features/syntax to C++ equivalents.
I'm having a hard time understanding where the core language stops and the standard library starts. I've encountered a lot of operators and/or traits which seems to have a special relationship with the compiler. For example, Rust has a trait (which from what I understand is like an interface) called Deref which let's a type implementing it be de-referenced using the * operator:
fn main() {
let x = 5;
let y = Box::new(x);
assert_eq!(5, x);
assert_eq!(5, *y);
}
Another example is the ? operator, which seems to depend on the Result and Option types.
Can code that uses those operators can be compiled without the standard library? And if not, what parts of the Rust language are depending on the standard library? Is it even possible to compile any Rust code without it?
The Rust standard library is in fact separated into three distinct crates:
core, which is the glue between the language and the standard library. All types, traits and functions required by the language are found in this crate. This includes operator traits (found in core::ops), the Future trait (used by async fn), and compiler intrinsics. The core crate does not have any dependencies, so you can always use it.
alloc, which contains types and traits related to or requiring dynamic memory allocation. This includes dynamically allocated types such as Box<T>, Vec<T> and String.
std, which contains the whole standard library, including things from core and alloc but also things with further requirements, such as file system access, networking, etc.
If your environment does not provide the functionality required by the std crate, you can choose to compile without it. If your environment also does not provide dynamic memory allocation, you can choose to compile without the alloc crate as well. This option is useful for targets such as embedded systems or writing operating systems, where you usually won't have all of the things that the standard library usually requires.
You can use the #![no_std] attribute in the root of your crate to tell the compiler to compile without the standard library (only core). Many libraries also usually support "no-std" compilation (e.g. base64 and futures), where functionality may be restricted but it will work when compiling without the std crate.
DISCLAIMER: This is likely not the answer you're looking for. Consider reading the other answers about no_std, if you're trying to solve a problem. I suggest you only read on, if you're interested in trivia about the inner workings of Rust.
If you really want full control over the environment you use, it is possible to use Rust without the core library using the no_core attribute.
If you decide to do so, you will run into some problems, because the compiler is integrated with some items defined in core.
This integration works by applying the #[lang = "..."] attribute to those items, making them so called "lang items".
If you use no_core, you'll have to define your own lang items for the parts of the language you'll actually use.
For more information I suggest the following blog posts, which go into more detail on the topic of lang items and no_core:
Rust Tidbits: What Is a Lang Item?
Oxidizing the technical interview
So yes, in theory it is possible to run Rust code without any sort of standard library and supplied types, but only if you then supply the required types yourself.
Also this is not stable and will likely never be stabilized and it is generally not a recommended way of using Rust.
When you're not using std, you rely on core, which is a subset of the std library which is always (?) available. This is what's called a no_std environment, which is commonly used for some types of "embedded" programming. You can find more about no_std in the Rust Embedded book, including some guidance on how to get started with no_std programming.

How do I use nested Vecs with wasm-bindgen?

It doesn't appear that nested Vecs work with wasm-bindgen. Is that correct?
My goal is to have a Game of Life grid in Rust that I can return as rows, rather than a 1D Vec which requires the JavaScript to handle the indexing. Two workarounds I've thought of are:
Implement a sort of custom "iterator" in Rust, which is a method which returns the rows one-by-one.
Hand a 1D array to JavaScript but write a wrapper in JavaScript which handles the indexing and exposes some sort of an iterator to the consumer.
I hesitate to use either of these because I want this library to be usable by JavaScript and native Rust, and I don't think either would be very idiomatic in pure Rust land. Any other suggestions?
You're correct that wasm-bindgen today doesn't support returning types like Vec<Vec<u8>>.
A good rule of thumb for WebAssembly is that big chunks of data (like vectors) should always live in the same location to avoid losing too much performance. This means that you might want to explore an interface where a JS object wraps a pointer into WASM memory, and all of its methods work with row/column indices but modify WASM memory to keep it as the source of truth.
If that doesn't work out, then the best way to implement this today is either of the strategies you mentioned as well, although both of those require some level of JS glue code to be written as well.

Turn a number into a byte string literal, similar to stringify!()

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.

What is the `isolate primitive` mentioned in the documentation of the "cereal" package?

There is an extensive collection of unique words in on the Haskell repository, cabal, (very slight exaggeration). Anyway today's term is isolate primitive. What is an isolate primitive? How does it compare to a non-isolate primitive? Unfortunately, I don't have the background to know most of the Haskell parlance, and Google isn't helping much on this one.
The nomenclature that I'm familiar with defines primitive as a type that has no super-type, and I've never seen isolate as a prefix anywhere.
The 'cereal' package provides a primitive function,
isolate :: Int -> Get a -> Get a
which is unique to that package. This function "isolates" a parsing action to operate using a fixed block of bytes. If the parsing function consumes less or more bytes, that is an error.
Thus, as opposed to binary, cereal "introduces an isolate primitive for parser isolation"
The documentation for 'isolate'
It's implementation
Isn't 'isolate' the name of a primitive defined in HackageDB::cereal ?
The isolate parser is called "primitive" because it is a simple parser that:
Can't be built from the other, provided parsers (not if it's really
primitive).
Can be used in combination with other parsers to build more complex
parsers.
It's a "primitive parser" in the same way that uint is a primitive type.

Why doesn't a string builder exist everywhere?

I sort of understand the motivation for a String Builder class, but do all languages have one? Should they? I'm thinking specifically of PHP, Perl, Python, and Ruby. I know C# and Java do. If the others don't, why not? Do they not suffer from the same implementation problem? Or do they not care?
Not all languages have a String builder.
C, for example, doesn't even have strings.
In C++, std::strings are mutable -- they can be changed, so there is no real need for a separate string builder class.
In C# (and the rest of .NET), string are immutable - they cannot be changed, only replaced This leads to the problem causing the need for StringBuilder.
Technically, .NET strings are reference types pretending to be value types. This was done to make they act more like the native types (int, float, decimal).
There is no need in string builders when string streams exist - file-like objects to construct strings.
For example, Python has StringIO:
from cStringIO import StringIO
sio = StringIO()
sio.write("Hello")
sio.write(" world!!")
sio.write(111)
sio.write('!')
print sio.getvalue()
Hello world!!111!
Ruby has its own StringIO too. In C++, the equivalent is std::stringstream.

Resources