Jump to content
Slate Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate Marble
Slate Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate Marble

Recommended Posts

The C programming language has truly passed the test of time. There are very few environments where it does not thrive. This is mainly due to its high execution performance, which, unfortunately, comes at a price: C does not support many of the features expected in a modern programming language.

Mozilla Research's Rust is an attempt to create a better mousetrap. Its language design remains focused on high performance and being close to hardware.

However, its syntax and compiler also take advantage of the various benefits offered by modern programming language research. Given that Mozilla's mission is the creation of an 'open web', it should not be surprising that the company is working tirelessly to bring its latest brainchild to the web. 

While Rust can, in theory, run on the client via systems such as Emscripten, its real power lies in the creation of efficient backend services.

How to start using Rust

qvgHPuNJQVkR3ouwvQLmvL.jpg

 The Rust installer provides a semi-graphic installation environment

While package managers such as 'apt-get' surely made developer's life easier, package list maintainers are, by and large, known to be no friends of excessive speed. Because of that, many, if not most, distributions' package caches are heavily outdated.

The Rust team has solved this problem by providing a dedicated installation script, which sets up the system it is run on efficiently. Deployment, then, is a two-step process: first, make sure that the CURL downloader/parser is available:

Then, in the second step, download the installer and pass it on to 'sh' using the pipe operator. 'Sh' is a shorthand for the default shell interpreter of your workstation, which will then proceed to run the code at hand:

During the installation, the Rust installer will display a variety of prompts similar in appearance to the ones shown in the picture on the right. Simply follow them to achieve a default installation. 

In some cases, the Rust deployment will fail with an error which is similar to "error: could not write rcfile file: '/home/tamhan/.bash_profile' ". If this happens during installation, use 'sudo -s' to get a root shell, and then rinse and repeat to proceed.

Run a sample

With that out of the way, it is time to run our first small program. Rust files, by default, have the file extension '.rs'. Create a file called 'firsttest.rs', and then provide it with the following piece  of code:

C and C++ programmers often wonder why invocations of the 'println' method require the use of an exclamation mark. The answer is simple: Rust implements 'println' as a macro, which gets invoked in a different way.

Given that Rust is a compiled language, our example must be processed before it can be run from the command line:

Advanced decay

Describing a complete programming language, such as Rust, in the limited space we have available here is impossible. So let's start by formally pointing you to Mozilla Research's comprehensive documentation. One feature which is sure to impress C programmers involves the use of the 'match' command: in addition to direct comparisons, it also enables the use of range operators to greatly simplify the design of advanced programs:

Garbage-at-hand

Classic garbage collection has its weaknesses: most implementations bring the program to a screeching halt from time to time. To get around that Rust uses a set of so-called 'zero-cost abstractions' to emulate a similar behaviour in a less annoying fashion.

In principle, every resource is created with an owner in a fashion similar to Qt's parent-child subsystem. However, a feature called 'borrowing' enables the programmer to transfer ownership between resources temporarily, thereby passing them around the system. 

Unfortunately, a complete discussion of the possibilities of Rust's memory manager would break the limits of this article – let it suffice to declare that Rust provides a very unorthodox, but workable form of memory management.

Create a new project

vStg9ZKEfqFffAue5e2wuL.jpg

 Similarities to NPM are purely coincidental...

While C and C++ code can be broken down into libraries, doing so is an annoying and somewhat uncomfortable task. Furthermore, making sure that all the required libraries are where they are needed is something even seasoned developers like to avoid.

The JavaScript community has long solved this problem via products such as NPM. Projects are described via a project structure file, which – among other things – contains references to libraries and other elements needed during the actual compilation run. 

In the case of Rust, a package manager called Cargo does a similar job. Creating a new project can be accomplished through the use of the 'cargo new' command in a fashion similar to the following:

When the creation process is complete, a folder structure similar to the one shown in the picture at the bottom of this page will be generated.

.toml files act as 'controllers' – in the case of our newly-generated project, the file contains the following structure:

Similarities to the .ini files of lore are not purely coincidential: in a fashion not dissimilar to NPM, the ancient configuration file format is also used to describe the configuration files used for Rust projects. The '[dependencies]' block is of special interest for us – it contains a list of all external libraries, which need to be present for the compilation to succeed.

Add a packet

Creating a web server by hand is an annoying job best left to masochists. We will, instead, opt for a framework. Sadly, finding the right one is not easy – as visiting AWWY's list of web development frameworks reveals, there are a lot of candidates.

We will pick Rocket, if only because it seems to be quite popular and has seen an update released in May 2018. Sadly, Rocket's developers tend to take a liking to newly introduced language features, which is why frequent updating of your Rust installation using the following commands is required:

The next step largely is a question of taste. Most libraries come with pre-provisioned starter projects, which developers can simply siphon from GitHub. Doing so for your 'prime' library is not necessarily a bad idea – although once more than one library is involved, a manual approach tends to be more fruitful.

Next, open the .toml file, then modify the 'dependencies' section as per the following in order to include a recent version of the Rocket framework:

Rocket is unique in that it requires the inclusion of a total of two packages: in addition to the main framework, a separate code generator file is also required. Either way, our version includes a specific version of the two libraries – Cargo can also accept wildcards, which enable the program to 'pick its poison' without any help from us.

With that out of the way, one problem remains: enter 'cargo run' in the folder containing the .toml file in order to perform an assisted compile, which will – among other things – download the relevant code libraries from the repository and compile the whole enchilada for you.

Next page: scaffolding and in-depth analysis

Create some scaffolding

2x5cnGLAe4tcnA9XBkEDvL.jpg

 Rust's package manager can also run compiled programs

Simply including and downloading a library is no fun: we want to see Rust in action. To achieve that, a sample program must be written – the scaffolding for which is the topic of the following steps.

Before we can really get coding, however, a small problem must be fixed. Rust's compiler does not allow for the use of advanced language features by default – if your application cannot be compiled due to feature use, you will need to fix the problem via the following command sequence:

Applying the 'set nightly' command in a folder containing a .toml file modifies it to mark its contents to be run using the latest version of rustc – with the flag set, the compile process should succeed. Next, open 'main.rs' and replace its contents with the following code:

Invoke 'cargo run' after saving the changes to see the output shown in the figure below. The package manager isn't limited to loading code, but can act as an advanced build tool.

3, 2, 1, lift off!

Rocket's developers, obviously, were inspired by the work of missile teams: make of this what you will. Like most other web frameworks, the actual applications are created as a collection of 'routes', which are assigned to a web server class. In this case, but one route is created – a 'get' call against '/' will yield the returning of the string 'Hello World'.

Incidentially, the main issue faced by developers coming to Rust from other languages is the somewhat odd syntax. Function return types are declared via an arrow following the header: 

Careful onlookers will determine that the snippet above generates a function returning a Boolean value: Rust knows about a few dozen data types, which must be formally specified at declaration to prevent the passing of invalid types in a fashion similar to TypeScript.

While the 'return' statement is supported by Rust; a special case occurs whenever the last line of a function is an expression. It is considered the 'return' value – a good example for this would look as per the following code:

With that now out of the way, our next step involves the creation of a brand new route:

Rust's language design advocates the use of attributes: the elements inside the '#[]' construct are additional properties, which get applied to any element standing nearby. 

In our particular case, the affected element is a function going by the name of 'world()'.

The next problem involves adding the new route to the above-mentioned web server element. This is easily accomplished as per the following:

This code is interesting mainly because of the use of the code generator: 'mount' takes the 'routes!' macro, which generates code on the fly. With that out of the way, you can now perform another recompile, which will enable you to convince yourself of the correctness of our code – the Rocket handler will now detect a total of two routes.

In-depth analysis

CgQXcpTGgAHFVtBZCM66Ze.jpg

 Rocket’s Runner is extremely talkative

Providing resources on request might make for a nice demo, but is lacking in practicability. A more interesting test involves accepting parameters from the client, and using them to modify the system behaviour as a whole.

The first step involves modifying the declaration of the route so it includes one or more parameters. Passing in a numeric and a string variable can be accomplished via a folder structure:

During compilation, the program will reveal a folder structure. Prove the correctness of the product by invoking http://localhost:8000/world/world/tam/40. The product also takes care of malformed requests – invoke http://localhost:8000/world/world/tam/tam to see a 404 error.

Understanding this behaviour requires a look at the routing infrastructure: like most other web frameworks, Rocket 'throws' incoming requests from route to route until one matches. Developers can also specify route rank via a numeric value:

Do the JSON

Another aspect involves the creation of well-formed JSON. To use it, a set of supporting libraries must be added to the .toml file – a lot of advanced features are not domiciled in Rocket, but in 'rocket_contrib':

Using the 'features' array lets us fine-tune the inclusion: you don't need to include all parts of the library. We furthermore load a group of helper libraries, which simplify serialisation.

Now we've edited the .toml file, it is time to return to the main Rust code. The newly-added elements must first be imported into the namespace:

A structure must be declared, which describes the format of the generated JSON object. We will limit ourselves to a numeric and a string value – be sure not to forget the attribute by mistake:

One problem remains: a JSON object must be built and returned in response to an incoming query:

Invoke the route we declared above, and feast your eyes on the output! 

CBGrNm6um8n9KQ3Py94NvL.jpg

To learn more about Rocket, check out this seriously useful guide

This article was originally published in issue 273 of creative web design magazine Web Designer. Buy issue 273 here or subscribe to Web Designer here.

Related articles:

View the full article

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

×