Skip to content

Commit

Permalink
mkdocs
Browse files Browse the repository at this point in the history
  • Loading branch information
levkk committed Oct 16, 2024
1 parent 5d74bfc commit bc99a96
Show file tree
Hide file tree
Showing 5 changed files with 164 additions and 8 deletions.
90 changes: 90 additions & 0 deletions docs/docs/getting-started.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# Getting started

Rust Web Framework (also called Rwf) has very few dependencies and is easy to install and use.

## Install Rust

If you haven't already, install the Rust compiler and tools from [rust-lang.org](https://rust-lang.org). Rwf doesn't use any nightly or experimental features,
so the stable version of the compiler will work.

## Create a project

Rwf can be used inside any Rust binary or library project. If you don't have a project already, you can create one with Cargo:

```bash
cargo init --bin rwf-web-app
```

## Install Rwf

Rwf has two packages:

* `rwf` which is the Rust crate[^1] used to build web apps
* `rwf-cli` which is a binary application that helps manage Rust projects built with Rwf

To install them, run the following while inside the root directory of your Cargo-created project:

```
cargo add rwf
cargo install rwf-cli
```

[^1]: A "crate" is a Rust package used as a dependency in other packages. It's analogous to "package" in JavaScript or Python.

## Building the app

With the packages installed, you're ready to launch your first web app in Rust. Rwf is built using the [MVC](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller) (Model-view-controller) design pattern,
so to get started, let's create a simple controller that will serve the index page (`/`) of your app:

```rust
use rwf::prelude::*;

#[derive(Default)]
struct Index;

#[async_trait]
impl Controller for Index {
async fn handle(&self, request: &Request) -> Result<Response, Error> {
Ok(Response::new().html("<h1>My first Rwf app!</h1>"))
}
}
```

`rwf::prelude::*` includes the vast majority of types, structs, traits and functions you'll be using when building controllers with Rwf.
Adding this declaration in your source files will make handling imports easier, but it's not required.

Rwf controllers are defined as Rust structs which implement the `Controller` trait. The trait is asynchronous, hence the `#[async_trait]` macro[^2],
and has only one method you need to implement: `async fn handle`. This method
acccepts an HTTP `Request`, and must return an HTTP `Response`.

In this example, we are returning `HTTP 200 - OK` with the body `<h1>My first Rwf app</h1>`. This is not strictly valid HTML,
but it'll work in all browsers for our demo purposes.

[^2]: The Rust language support for async traits is still incomplete. The `async_trait` crate helps with writing async traits in an ergonomic way.

## Launching the server

Once you have at least one controller, you can add it to the Rwf HTTP server and launch it on the address and port of your choosing:

```rust
use rwf::http::{self, Server};

#[tokio::main]
async fn main() -> Result<(), http::Error> {
// Configure then logger (stderr with colors by default)
Logger::init();

Server::new(vec![
route!("/" => Index),
])
.launch("0.0.0.0:8000")
.await
}
```

Rwf uses the `log` crate for logging. `Logger::init()` automatically configures it for your app using `env_logger`, but if you prefer, you can configure logging yourself
using the crate of your choosing.

Once the server is launched, you can visit the index page by pointing your browser to [http://localhost:8000](http://localhost:8000).

Full code for this is available in GitHub in [examples/quick-start](https://github.com/levkk/rwf/tree/main/examples/quick-start).
3 changes: 3 additions & 0 deletions docs/docs/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Introduction

[Rwf](https://github.com/levkk/rwf) is a framework for building web applications in the Rust programming language.
34 changes: 34 additions & 0 deletions docs/mkdocs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
site_name: Rust Web Framework
theme:
name: material
palette:
# Palette toggle for automatic mode
- media: "(prefers-color-scheme)"
toggle:
icon: material/brightness-auto
name: Switch to light mode

# Palette toggle for light mode
- media: "(prefers-color-scheme: light)"
scheme: default

toggle:
icon: material/brightness-7
name: Switch to dark mode

# Palette toggle for dark mode
- media: "(prefers-color-scheme: dark)"
scheme: slate
toggle:
icon: material/brightness-4
name: Switch to system preference
docs_dir: docs
markdown_extensions:
- pymdownx.highlight:
anchor_linenums: true
line_spans: __span
pygments_lang_class: true
- pymdownx.inlinehilite
- pymdownx.snippets
- pymdownx.superfences
- footnotes
30 changes: 30 additions & 0 deletions docs/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
babel==2.16.0
certifi==2024.8.30
charset-normalizer==3.4.0
click==8.1.7
colorama==0.4.6
ghp-import==2.1.0
idna==3.10
Jinja2==3.1.4
Markdown==3.7
MarkupSafe==3.0.1
mergedeep==1.3.4
mkdocs==1.6.1
mkdocs-get-deps==0.2.0
mkdocs-material==9.5.41
mkdocs-material-extensions==1.3.1
mkdocs-terminal==4.6.0
packaging==24.1
paginate==0.5.7
pathspec==0.12.1
platformdirs==4.3.6
Pygments==2.18.0
pymdown-extensions==10.11.2
python-dateutil==2.9.0.post0
PyYAML==6.0.2
pyyaml_env_tag==0.1
regex==2024.9.11
requests==2.32.3
six==1.16.0
urllib3==2.2.3
watchdog==5.0.3
15 changes: 7 additions & 8 deletions examples/quick-start/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
use rwf::http::Server;
use rwf::http::{self, Server};
use rwf::prelude::*;

#[derive(Default)]
struct IndexController;
struct Index;

#[async_trait]
impl Controller for IndexController {
async fn handle(&self, _request: &Request) -> Result<Response, Error> {
Ok(Response::new().html("<h1>Hey Rum!</h1>"))
impl Controller for Index {
async fn handle(&self, request: &Request) -> Result<Response, Error> {
Ok(Response::new().html("<h1>My first Rwf app!</h1>"))
}
}

#[tokio::main]
async fn main() {
async fn main() -> Result<(), http::Error> {
Logger::init();

Server::new(vec![IndexController::default().route("/")])
Server::new(vec![route!("/" => Index)])
.launch("0.0.0.0:8000")
.await
.expect("error shutting down server");
}

0 comments on commit bc99a96

Please sign in to comment.