{"id":13495154,"url":"https://github.com/mugli/rust-for-nodejs-developers","last_synced_at":"2025-03-28T16:31:35.152Z","repository":{"id":138512467,"uuid":"177425390","full_name":"mugli/rust-for-nodejs-developers","owner":"mugli","description":"Code examples for people learning Rust coming from Node.js","archived":true,"fork":false,"pushed_at":"2019-03-25T15:46:56.000Z","size":11,"stargazers_count":8,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-10-31T10:36:32.371Z","etag":null,"topics":["demo","examples","guide","howto","javascript","learning","nodejs","reference","rust","rust-lang"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mugli.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2019-03-24T14:24:45.000Z","updated_at":"2024-05-18T17:39:08.000Z","dependencies_parsed_at":null,"dependency_job_id":"fd1babef-0ce5-46ca-b8ec-a6261603e67d","html_url":"https://github.com/mugli/rust-for-nodejs-developers","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mugli%2Frust-for-nodejs-developers","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mugli%2Frust-for-nodejs-developers/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mugli%2Frust-for-nodejs-developers/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mugli%2Frust-for-nodejs-developers/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mugli","download_url":"https://codeload.github.com/mugli/rust-for-nodejs-developers/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246062818,"owners_count":20717690,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["demo","examples","guide","howto","javascript","learning","nodejs","reference","rust","rust-lang"],"created_at":"2024-07-31T19:01:31.728Z","updated_at":"2025-03-28T16:31:34.773Z","avatar_url":"https://github.com/mugli.png","language":null,"funding_links":[],"categories":["Others"],"sub_categories":[],"readme":"# Rust for Node.js Developers\n\n![](https://img.shields.io/badge/license-MIT-green.svg)\n\n(**Work in progress**. Done: 4 of 60 planned examples)\n\nThis guide full of examples is intended for people learning Rust that are coming from Node.js, although the vice versa can work too. I made this because I'm learning Rust myself, hoping maybe it'll also help other people with similar background and interest. I tried to learn idiomatic rust along the way, but please feel free to send PR if you find something that can be improved.\n\nThis is a [cookbook style](https://rust-lang-nursery.github.io/rust-cookbook/) guide. However, it doesn't explain how to install Rust, what cargo is etc. If you need help with that, this might be a good starting point, which is written in tutorial style: https://github.com/Mercateo/rust-for-node-developers\n\n## Contents\n\n- [Examples](#examples)\n  - [comments](#comments)\n  - [printing](#printing)\n  - [variables](#variables)\n  - [types](#types)\n    - [bool](#types)\n    - [number](#types)\n    - [string](#types)\n    - [array](#types)\n    - [object](#types)\n    - [function](#types)\n    - [closure](#types)\n- [Contributing](#contributing)\n- [Acknowledgement](#acknowledgement)\n- [License](#license)\n\n## Examples\n\nAll sample code is available in [examples/](examples/)\n\nUse `cargo-script` for running Rust `.rs` codes:\n\n```bash\n# Install cargo-script\ncargo install cargo-script\n\n# Run filename.rs\ncargo script filename.rs\n```\n\n_Note: Sometimes the Rust source will have comment like this:_\n\n```rust\n// cargo-deps: time=\"0.1.25\"\n```\n\n_This is only to let `cargo script` know that it needs to download `version 0.1.25` of [`time` crate](https://crates.io/crates/time) before running the file. You don't need that comment in a Rust project file created with `cargo new` command._\n\n### comments\n\n---\n\n#### Node.js\n\n```js\n// This is a line comment\n\n/*\n  This is a block comment\n*/\n```\n\n#### Rust\n\n````rust\n\n/// Documentation comments look like this and support markdown notation.\n/// # Examples\n///\n/// ```\n/// let five = 5\n/// ```\n///\n/// Documentation comments must come before what they document.\n/// The code will not compile if we place this comment inside the function!\nfn main() {\n    // This is a line comment\n    // that extend multiple lines like this.\n\n    /*\n      Note that Rust supports block comment too, but line comments are preferred in general.\n    */\n}\n\n````\n\n### printing\n\n---\n\n#### Node.js\n\n```js\nconsole.log('hello world');\nconsole.log('hello %s', 'world');\nconsole.log('hello %d %s', 5, 'worlds');\n```\n\nOutput\n\n```bash\nhello world\nhello world\nhello 5 worlds\n```\n\n#### Rust\n\n`println!` is a [macro](https://doc.rust-lang.org/book/ch19-06-macros.html)\n\n```rust\n\nfn main() {\n    println!(\"hello world\");\n    println!(\"hello {}\", \"world\");\n    println!(\"hello {} {}\", 5, \"worlds\");\n}\n\n```\n\nOutput\n\n```bash\nhello world\nhello world\nhello 5 worlds\n```\n\n### variables\n\n---\n\n#### Node.js\n\n```js\n// function scoped\nvar foo = 'foo';\n\n// block scoped\nlet bar = 'bar';\n\n// constant\nconst qux = 'qux';\n```\n\n#### Rust\n\nVariables are block scoped in Rust. They are immutable unless you declare them with `mut` keyword. But they can be shadowed!\n\n```rust\n#[allow(unused_variables)]\n#[allow(unused_assignments)]\n#[allow(dead_code)]\nfn main() {\n    // All variables are block scoped.\n\n    // Variables are by default immutable.\n    let foo: \u0026str = \"foo\";\n\n    // And you can redeclare variables! This is called shadowing.\n    // Useful during data transformation when you don't want to\n    // name a lot of intermediate and temporary variables.\n    let foo: isize = 42;\n\n    // Type inferred\n    let bar = \"bar\";\n\n    // Mutable\n    let mut baz: \u0026str = \"baz\";\n    baz = \"bazbaz\";\n\n    // Rust has constants. But they are different than immutable variables.\n    // Constants evaluate at compile-time, where variables evaluate at run-time.\n    // Constant values are effectively an alias for a literal value.\n    // In short, constants represent a value, not a memory address.\n    const MEANING: isize = 42;\n}\n\n```\n\n### types\n\n---\n\n#### Node.js\n\n```js\n// primitives\nconst myBool = true;\nconst myNumber = 10;\nconst myString = 'foo';\nconst mySymbol = Symbol('bar');\nconst myNull = null;\nconst myUndefined = undefined;\n\n// object types\nconst myObject = {};\nconst myArray = [];\nconst myFunction = function() {};\nconst myError = new Error('error');\nconst myDate = new Date();\nconst myRegex = /a/;\nconst myMap = new Map();\nconst mySet = new Set();\nconst myPromise = Promise.resolve();\nconst myGenerator = function*() {};\nconst myClass = class {};\n\nfunction makeAdder(x) {\n  // JavaScript closure\n  return function(y) {\n    return x + y;\n  };\n}\n\nvar add5 = makeAdder(5);\nvar add10 = makeAdder(10);\n\nconsole.log(add5(2)); // 7\nconsole.log(add10(2)); // 12\n```\n\n#### Rust\n\n```rust\n#[allow(unused_variables)]\n#[allow(dead_code)]\nfn main() {\n    // Primitives\n\n    // Scalar primitives: integers\n    let my_bool: bool = true;\n    let my_int: isize = 10; // pointer size\n    let my_int8: i8 = 10;\n    let my_int16: i16 = 10;\n    let my_int32: i32 = 10;\n    let my_int64: i64 = 10;\n    let my_int128: i128 = 10;\n\n    // Scalar primitives: unsigned integers\n    let my_uint: usize = 10; // pointer size\n    let my_uint8: u8 = 10;\n    let my_uint16: u16 = 10;\n    let my_uint32: u32 = 10;\n    let my_uint64: u64 = 10;\n    let my_uint128: u128 = 10;\n\n    // Scalar primitives: floats\n    let my_float32: f32 = 10.5;\n    let my_float64: f64 = 10.5;\n\n    // Scalar primitives: Unicode characters, 4 bytes each\n    let my_char: char = '🐶'; // Noticed the single quotes? 👈\n\n    // Scalar primitives: bool\n    let my_bool: bool = false;\n\n    // Scalar primitives: \"unit type\". The only possible value is an empty tuple: ()\n    let my_unit: () = ();\n\n    // ----------------------------------------------------------------------\n    // ----------------------------------------------------------------------\n    // ----------------------------------------------------------------------\n\n    // Compound primitives: Tuple\n    let tup: (i32, f64, u8) = (500, 6.4, 1);\n    let five_hundred = tup.0; // Accessing tuple. Noticed the dot? 👈\n\n    // Compound primitives: Array\n    // Arrays in Rust are different from arrays in some other languages\n    // because arrays in Rust have a fixed length, like tuples.\n    //\n    // Since an array has a fixed size, even if the array’s elements\n    // are modified, it cannot grow or shrink.\n    //\n    // Unlike a tuple, every element of an array must have the same type.\n    //\n    // If you need the collection to grow or shrink, you'll need to use a vector\n    // instead of an array.\n    let a = [1, 2, 3, 4, 5];\n    let first = a[0]; // Accessing array\n\n    // ----------------------------------------------------------------------\n    // ----------------------------------------------------------------------\n    // ----------------------------------------------------------------------\n\n    // Custom type: Struct\n\n    // A unit struct\n    struct Nil;\n\n    // A tuple struct\n    struct Pair(i32, f32);\n\n    // A struct with two fields\n    struct Point {\n        x: f32,\n        y: f32,\n    }\n\n    // Instantiate a struct\n    let point = Point { x: 0.3, y: 0.4 };\n\n    // Access the fields of the point\n    println!(\"point coordinates: ({}, {})\", point.x, point.y);\n\n    // Instantiate a tuple struct\n    let pair = Pair(1, 0.1);\n\n    // Access the fields of a tuple struct\n    println!(\"pair contains {:?} and {:?}\", pair.0, pair.1);\n\n    // ----------------------------------------------------------------------\n    // ----------------------------------------------------------------------\n    // ----------------------------------------------------------------------\n\n    // Custom type: Enum\n\n    enum WebEvent {\n        // An `enum` may either be `unit-like`:\n        PageLoad,\n        // like tuple structs:\n        KeyPress(char),\n        // or like structures:\n        Click { x: i64, y: i64 },\n    }\n\n    let pressed = WebEvent::KeyPress('x');\n    let load = WebEvent::PageLoad;\n    let click = WebEvent::Click { x: 20, y: 80 };\n\n    // ----------------------------------------------------------------------\n    // ----------------------------------------------------------------------\n    // ----------------------------------------------------------------------\n\n    // Function \u0026 closures\n    fn f() {\n        println!(\"I have been called!\")\n    };\n    let my_function_pointer = f;\n    my_function_pointer();\n\n    // Closures in Rust are anonymous functions you can save in a variable or\n    // pass as arguments to other functions.\n    // They are also called lambda expressions or lambdas,\n    // they can capture their enclosing environment.\n    let closure_annotated = |i: i32| -\u003e i32 { i + 1 };\n    let closure_inferred = |i| i + 1;\n\n    println!(\"closure_annotated: {}\", closure_annotated(10));\n    println!(\"closure_inferred: {}\", closure_inferred(10));\n\n    // A lot to unpack here!\n    // For detail explanation: https://doc.rust-lang.org/book/ch19-05-advanced-functions-and-closures.html\n    fn make_adder(x: i32) -\u003e Box\u003cdyn Fn(i32) -\u003e i32\u003e {\n        Box::new(move |y| x + y)\n    }\n    let add_5 = make_adder(5);\n    let add_10 = make_adder(10);\n    println!(\"{}\", add_5(2)); // Output: 7\n    println!(\"{}\", add_10(2)); // Output: 12\n}\n\n```\n\n## Contributing\n\nPull requests are welcome!\n\nPlease submit a pull request for new interesting additions or for general content fixes.\n\nIf updating code, update both the README and the code in the [examples](examples/) folder.\n\n## Acknowledgement\n\nThis project is inspired by [Golang for Node.js Developers](https://github.com/miguelmota/golang-for-nodejs-developers) repo.\n\n## License\n\n[MIT](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmugli%2Frust-for-nodejs-developers","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmugli%2Frust-for-nodejs-developers","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmugli%2Frust-for-nodejs-developers/lists"}