from cargo init to cargo publish

Introduction

Hello Rustians, today we will talk about building and publishing your own crate on crates.io.
Rust is an open-source programming language, thanks to which everyone can contribute to its development in many ways. One of these ways is to write and publish your own crate. A crate is a modular unit of code that can be used by other developers to create their software solutions.
In this article, I will show you how to write your own library and publish it on crates.io For example own project for working with matrices.

Disclaimer

The author of the article is also learning to program, so the article may (they are) shortcomings and errors, please treat with understanding and correct in the comments.

Let’s start from the base

To write our own crate, we need, oddly enough, to create a project. To do this, open a code editor or terminal, open the desired directory and write cargo init. After that, several files appeared in the project folder. Open the file main.rs and see the following code:

//main.rs
fn main() {   
  println!("Hello, world!");
}

Cool, but most likely no one wants to include this in their project), so let’s create a couple more files: lib.rs and matrix2.rs matrix2.rs declare the structure Matrix2

//matrix2.rs
#[derive(Debug)]
pub struct Matrix2<T: Clone + Copy> {
    pub(crate) rows: usize,
    pub(crate) columns: usize,
    pub(crate) elems: Vec<Vec<T>>,
}

When declaring, we specify the pub access modifier so that structure objects can be created outside of this file, we implement the Debug trait for it so that its contents can be output to the console. We also specify the pub(crate) access modifier for all fields, which means that the structure fields will be visible everywhere inside the crate, but will not be available to the user. To file lib.rs add just one line of code:

//lib.rs
pub mod matrix2;

Which allows us to create Matrix2 objects in main.rs file. But we can’t initialize them yet, so let’s add the new method, which accepts 4 matrix values:

//matrix2.rs
impl<T: Clone + Copy> Matrix2<T> {
    pub fn new(m1: T, m2: T, m3: T, m4: T) -> Matrix2<T> {
        Matrix2 {
            rows: 2,
            columns: 2,
            elems: vec![vec![m1, m2], vec![m3, m4]],
        }
    }
}

After that, you need to rewrite the file a little main.rs

//main.rs
extern crate hav;

use hav::matrix2::Matrix2;

fn main() {
    let m = Matrix2::new(1, 2, 3, 4);
    println!("{:?}", m);
}

Now we can build the project with the command cargo build and run it with cargo run. In the console we get:

Finished dev [unoptimized + debuginfo] target(s) in 0.02s
     Running `target\debug\main.exe`
Matrix2 { rows: 2, columns: 2, elems: [[1, 2], [3, 4]] }

Matrix2 this is our 2 by 2 matrix with elements 1, 2, 3, 4.
Cool! We have written part of the library, now you can upload it to githubyou will need it to publish it.

Comments

Before publishing a crate in the public domain, it would be nice to write documentation for it. This is necessary to make it easier for the user to deal with the library.
This is done by writing ///

For example:

// matrix2.rs
/// Structure for matrix2
#[derive(Debug)]
pub struct Matrix2<T: Clone + Copy> {
    pub(crate) rows: usize,
    pub(crate) columns: usize,
    pub(crate) elems: Vec<Vec<T>>,
}

/// Creates new matrix2
impl<T: Clone + Copy> Matrix2<T> {
    pub fn new(m1: T, m2: T, m3: T, m4: T) -> Matrix2<T> {
        Matrix2 {
            rows: 2,
            columns: 2,
            elems: vec![vec![m1, m2], vec![m3, m4]],
        }
    }
}

Thus, with the help ///we wrote a piece of documentation for our crate
After that, you can run the cargo command doc --openthis will create the crate page in target directories, and the flag --open immediately open this file in the browser.

The page has opened and we can even click on matrix2 and see the structure Matrix2 with our comment.

Click on it and we will see, in addition to the implemented traits, a description of the method new

In addition to modules and structures, public functions from the file will also be added to the documentation. lib.rs :

// lib.rs
pub mod matrix2;

/// Hello from my crate!
pub fn print_hello() {
    println!("Hello, world!");
}

You can also add a library description with //!

// lib.rs
//! # hav
//!
//! It's my crate!

/// Matrix2
pub mod matrix2;

/// Hello from my crate!
pub fn print_hello() {
    println!("Hello, world!");
}

So, we learned how to document our library, it’s time to publish it!

Adding metadata

But no, I cheated, you need to add data about your library to .toml file:

[package]
name = "hav"
version = "0.1.0"
edition = "2021"
description = ""
license = ""
homepage = ""
repository = ""
documentation = ""
readme = ""
categories = [""]
keywords = [""]

[dependencies]

After that, you can already proceed to the last step.

Publication

To publish, simply write the command cargo publish
You can also specify flags, for example --no-depsto avoid publishing your crate’s dependencies. A complete list of flags can be found here.
We execute the command and what, is it really all? Of course not.
For publication on crates.io, oddly enough, you need to register there, or rather log in through github. Let’s move on by this link and get your API key.
Execute the command cargo login <your_key> .
Now we write cargo publish and that’s it! Our library ends up on crates.io, and after a while on the site https://docs.rs/ documentation appears

Conclusion

In this article, we learned how to create our own Rust crate and publish it on crates.io.

The library I published and its source code can be viewed here.

Thank you all for your time, I hope this not very detailed guide will help someone!

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *