Practical Rust:
API Expectations
You may have some expectations if you come to Rust from other programming languages.
You may expect:

1. Polymorphism
2. Inheritance
3. Macros "Polymorphism" broadly covers a few common topics. "Macros" are a kind of metaprogramming.
Wikipedia:

"polymorphism is the provision of a single interface to entities of different types" From Wikipedia: In programming languages and type theory, polymorphism is the provision of a single interface to entities of different types or the use of a single symbol to represent multiple different types.
Kinds of Polymorphism

1. "Ad-hoc" polymorphism
    - Argument overloads, variadic functions
2. Parametric polymorphism
    - Generics
3. Subtyping / inclusion
    - Interfaces, Traits We'll discuss Rust's Generics and Traits in more detail shortly
JavaScript function argument overloading ("ad-hoc" polymorphism)

function do_polymorphic(a, b, c = true) {
  if (b === undefined) {
    b = something()
  }
  c = Boolean(c)
  b = Boolean(b)
  if (typeof a !== "number") { /* ... */ }
  // ...
}
    
JavaScript variadic function including type checking.
Simple C# function overloading ("ad-hoc" polymorphism)

class Thingy {
    void DoTwo(int a, bool c) {
        DoThree(a, b, false);
    }

    void DoThree(int a, bool b, bool c) {
        // ...
    }
}
    
Simple Java-style C# function overloading without abstract methods.
"But there's no (ad-hoc) polymorphism in Rust!"

Well, yes, under the hood everything in Rust is monomorphized. Generics, are of course, parametric polymorphism. And the monomorphization means that generics are flattened into every applicable variation. Largely an implementation detail related to LLVM assembly generation.
In Rust
Generics & Traits are used in place of argument / function overloading.
Generics is the topic of generalizing types and functionalities to broader cases. That is; Generics are abstract stand-ins for concrete types or other properties.
TypeScript generics (parametric polymorphism) & constraints (subtype)

interface Lengthwise {
  length: number;
}

function loggingIdentity<T extends Lengthwise>(arg: T): T {
  //       generic param ^         ^ constraint

  console.log(arg.length);
  return arg;
}
    
Generic parameters in Rust are always within angle brackets (< >).

MyStruct<T> {}
//       ^

a_function::<String>();
//           ^

impl<T> From<T> for T {}
//   ^       ^      ^
    
Traits: Defining Shared Behavior in Generics

Traits are similar to a feature often called interfaces in other languages, although with some differences. This is subtype polymorphism A trait tells the Rust compiler about functionality a particular type has and can share with other types. We can use traits to define shared behavior in an abstract way. We can use trait bounds to specify that a generic can be any type that has certain behavior.
Trait bounds on generic parameters specify which types are applicable.

MyStruct<T: Debug> {}
//          ^

fn a_function<T: FromStr>(data);
//               ^

fn a_function(data impl FromStr);
//      (same as above) ^
    
Similar to TypeScript or C# constraints
Accepting conversions: Rust's "function overloads"

use http_types::Request;

fn accepts_request(req: impl Into<Request>) {
    let req = req.into();
    // ...
}
    
Infallible Conversion Traits

impl From<OtherType> for MyType {}

impl Into<OtherType> for MyType {}
    
Fallible Conversion Traits (Returns Result<T>)

impl TryFrom<OtherType> for MyType {}

impl TryInto<OtherType> for MyType {}
    

use std::convert::TryInto;
use url::Url;

// Generically accept any type which implements `TryInto<Url>`.
fn get(url: impl TryInto<Url>) -> Result {
    let url = url.try_into()?;
    // ...
}

fn main() -> Result {
    // All of these work!
    get("https://example.org")?; // Static literal

    let owned_resizable_string: String = "https://example.org".to_string();
    get(&owned_resizable_string)?; // Borrowed

    let url_struct: Url = "https://example.org".parse::<Url>()?;
    get(url_struct)?;
}
    
Note: From & Into
are also useful for general conversions, not just for polymorphism.

impl<T, U> Into<U> for T
where
    U: From<T>,
{
    fn into(self) -> U {
        U::from(self)
    }
}


impl<T> From<T> for T {
    fn from(t: T) -> T {
        t
    }
}
    
1. Polymorphism
2. Inheritance
3. Macros
"But there's no inheritance in Rust!"

Yes this one is technically true. But, effectively the same thing is representable.
Inner struct wrapping pattern

// "sub class"
struct WrapsString {

    // "super class"
    // This is private by default.
    inner: String,

    pub other_field: u32,
};
    
Inner could be 'pub', as in in publicly exposed, but we probably don't want that...
By-reference conversion traits.

impl AsRef<OtherType> for MyType {}

impl AsMut<OtherType> for MyType {}
    
By-reference mutable access to our 'inner' field.

struct WrapsString {
    inner: String,
}

impl AsMut<str> for WrapsString {
    fn as_mut(&mut self) -> &mut str {
        &mut self.inner
        // Implicit return
    }
}
    

struct WrapsString { inner: String }
impl AsMut<str> for WrapsString {}

fn modify_string(string: impl AsMut<str>) {
    let string = string.as_mut();
    // Mutate this string in-place in some way
}

fn main() {
    let mut wrapper = WrapsString { inner: "banana".to_string() };
    modify_string(&mut wrapper);
}
    
We can act on the wrapper as if it was a mutable reference to the inner type!
These conversions can be used outside of generic arguments too!

use http_types::{Response, StatusCode};

let mut res = Response::new(StatusCode::Ok);
res.insert_header("cats", "good");

// Left-hand type inference.
// "Down-casts" a reference to the inner headers structure.
let headers: Headers = res.as_ref();
    
"Extension" Traits

Add functionality to existing types! Rust also has a unique concept of extending functionality via a local trait onto existing types.
Extension traits

use std::vec::Vec;

trait NewFunctionality<T> {
    fn some_method(&self) -> T
}

impl<T> NewFunctionality<T> for Vec<T> {
    fn some_method(&self) -> T {
        // ...
    }
}
    
1. Polymorphism
2. Inheritance
3. Macros
Macros: Metaprogramming

A way of writing code that writes other code.
Macros: missing from JavaScript, TypeScript, C#, Go, etc. Though, JS "Transpilers" themselves are kinda macro-like.
Rust macros are not text substitution! C-style macros are like telling your code 'yeah just copy that from stackoverflow'. Rust macros return full checked valid rust code, and can be recursive!
Rust: declarative & procedural macros

1. Simple declarative macro expansion
2. Custom #[derive] macros
3. Attribute-like macros
4. Function-like macros

// A simple macro_rules! declarative expansion
println!("Hello World from {}", std::process::id());
    
A couple different invocation syntaxes exist

println!("Hello World from {}", std::process::id());

let growable_array = vec![1, 2, 3, 4, 5];

lazy_static! {
    static ref HASHMAP: HashMap<u32, &'static str> = HashMap::new();
}
    
Macros are Rust's most typical answer to variadic arguments

let growable_array = vec![1, 2, 3, 4, 5];
    
I mentioned variadic arguments earlier but never covered them ...

preroll::main!("geolocality", setup_app_state, setup_routes);

#[macro_export]
macro_rules! main {
    ($service_name:tt, $routes_fns:tt) => {
        $crate::main!($service_name, async { Ok(()) }, routes_fns);
    };

    ($service_name:tt, $state_setup:tt, $routes_fns:tt) => { };

    ($service_name:tt, $state_setup:tt, $custom_setup:tt, $routes_fns:tt) => { };
}

use geo_types::Coordinate;
use mockall::automock;
use serde::Deserialize;

// An annotation-style procedural macros
#[derive(Deserialize)]
#[automock]
struct JsonInput {
    waypoints: Vec<Coordinate<f64>>,
}
    

// Nightly asm feature
#![feature(asm)]

fn main() {
    let buf = "Hello from asm!\n";
    let ret: i32;
    unsafe {
        asm!(
            "syscall",
            in("rax") 1, // syscall number
            in("rdi") 1, // fd (stdout)
            in("rsi") buf.as_ptr(),
            in("rdx") buf.len(),
            out("rcx") _, // clobbered by syscalls
            out("r11") _, // clobbered by syscalls
            lateout("rax") ret,
        );
    }
    println!("write returned: {}", ret);
}
    
vgtk

fn view(&self) -> VNode {
  gtk! {
      <Application::new_unwrap(None, ApplicationFlags::empty())>
          <Window border_width=20 on destroy=|_| Message::Exit>
              <HeaderBar title="inc!" show_close_button=true />
              <Box spacing=10 halign=Align::Center>
                  <Label label=self.counter.to_string() />
                  <Button label="inc!" image="add" always_show_image=true
                          on clicked=|_| Message::Inc />
              </Box>
          </Window>
      </Application>
  }
}
    

use inline_python::python;

fn main() {
    let who = "world";
    let n = 5;
    python! {
        for i in range('n):
            print(i, "Hello", 'who)
        print("Goodbye")
    }
}
    
Database-checked SQL queries!

let EventHistory { event_history } = sqlx::query_as!(
    EventHistory,
    r#"
    SELECT
        json_agg(events.*) AS event_history
    FROM events
    WHERE
        events.subject_id = $1
    "#,
    order_id
)
.fetch_one(conn.acquire().await?)
.await?;
    
Practical Rust:
API Expectations

1. Polymorphism
2. Inheritance
3. Macros