Publishing First Rust Crate
Tags: rust, firstpost
Published: 2021-05-30 19:27:29

# Background
I am a College Student and have been using and experimenting with Rust for a while now. I wrote a small crate to identify the various video formats using their magic bytes as kinda a project for getting selected in GSOC21. Sadly, it didn't work out but I thought now that I have the crate, I might as well publish it. I remember searching for it a year ago when I was trying to create a Plex like media server in Rust and coming up empty. So, I started looking at the Crates.io [documentation](https://doc.rust-lang.org/cargo/reference/publishing.html) and found it to be quite a painless process.

# Introduction to Crate
The crate I wanted to publish was [media_infer](https://github.com/Ayush1325/media_infer). It basically reads the starting bytes of a file or stream of bytes and tries to figure out the video container. The resources for the various magic bytes I used are given below: 
- [Wikipedia](https://en.wikipedia.org/wiki/List_of_file_signatures)
- [Garykessler](https://www.garykessler.net/library/file_sigs.html)

# Steps to Publish
## Create an account in Crates.io
## Acquire API Token
You will need to create a new token the first time. It seems every device should have a different token. After the token is created, the Crates.io token section gives the command to type and it is something like this:
```
$ cargo login <token>
```
## Add Metadata to the Cargo.toml
Set the fields like:
- authors
- license or license-file
- description
- homepage
- documentation
- repository
- readme
- keywords
- categories
The versioning should be kept in mind since there is no way to edit an already published crate.
## Check LICENSE and README files
README file from the git repository is used and should be in markdown. Crates.io doesn't seem to recognize Org documents.
## Check Package
The files that will be included in teh .crate file can be checked using:
```
$ cargo package --list
```
Cargo will automatically ignore files ignored by your version control system when packaging, but if you want to specify an extra set of files to ignore you can use the exclude key in the manifest:
```toml
[package]
# ...
exclude = [
    "public/assets/*",
    "videos/*",
]
```
Or include:
```toml
[package]
# ...
exclude = [
    "public/assets/*",
    "videos/*",
]
```
Crates.io currently has a 10MB size limit on the .crate file.
## Dry Run
Cargo has a pretty nifty command which basically checks if everything is in order and even gives warnings about things that can be improved.
```
$ cargo publish --dry-run
```
## Publish
Once everything is finalized, the crate can be published using the simple command.
```
$ cargo publish
```
Once a version is already published, the same version cannot be published again even if the previous publish has been yanked.
# Conclusion
This was the fist time I have published a library for any language, so it was kind of a great learning experience to actually do it myself. Earlier even though I knew what the crates were, it used to seem kind of like a difficult goal to achieve. Now, I think I understand and appreciate the crates a lot more.
# Resources
- [Crates.io Publish Guide](https://doc.rust-lang.org/cargo/reference/publishing.html)
- [Crates.io media_infer](https://crates.io/crates/media_infer)
- [Github media_infer](https://github.com/Ayush1325/media_infer)