Skip to content

Commit

Permalink
Merge pull request #2 from nwrenger/marker-rework
Browse files Browse the repository at this point in the history
Marker rework
  • Loading branch information
nwrenger authored Aug 5, 2024
2 parents f5a85c6 + a22a0a8 commit e62d603
Show file tree
Hide file tree
Showing 8 changed files with 1,040 additions and 1,072 deletions.
9 changes: 6 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "gluer"
version = "0.6.1"
version = "0.7.0"
edition = "2021"
authors = ["Nils Wrenger <[email protected]>"]
description = "A wrapper for Rust frameworks that eliminates redundant type and function definitions between the frontend and backend"
Expand All @@ -12,11 +12,14 @@ readme = "README.md"
license = "MIT"

[lib]
proc-macro = true

[dependencies]
gluer-macros = { path = "macros", version = "0.6.1" }
axum = "0.7.5"
quote = "1.0"
syn = { version = "2.0.62", features = ["full"] }
proc-macro2 = "1.0"

[dev-dependencies]
axum = "0.7.5"
tokio = { version = "1.39.2", features = ["macros", "rt-multi-thread"] }
serde = { version = "1.0", features = ["derive"] }
66 changes: 26 additions & 40 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,13 @@ Add this to your `Cargo.toml`:

```toml
[dependencies]
gluer = "0.6.1"
gluer = "0.7.0"
```

## Features

- Define routing and API generation as outlined in [How to use](#how-to-use).
- Everything is done on macro expansion (compile time), even the generating of the TypeScript file.
- Infer input and output types of functions.
- Support `axum`'s types completely.
- Convert Rust structs to TypeScript interfaces.
Expand Down Expand Up @@ -120,16 +121,16 @@ async fn book_state() -> Json<BookState> {
```

### Step 2: Add Routes

Use the `Api` wrapper around `axum`'s Router to add routes. Utilize the `extract!` macro to gather all necessary information from the functions. Note that inline functions cannot be used, as the function names of the generated TypeScript file are inferred from the handler function names.
Use the `route!` macro with `axum`'s Router to add routes. This enables the `generate` macro to identify the route and generate corresponding functions, structs, types, and enums. Note that inline functions cannot be used because the function names in the generated TypeScript file are inferred from the handler function names.

```rust
use axum::{
routing::get,
Json,
Router,
extract::Path,
};
use gluer::{Api, extract, metadata};
use gluer::{route, metadata};

// without `#[metadata]`, it's non-API-important
async fn root() -> String {
Expand All @@ -142,43 +143,26 @@ async fn hello(Path(h): Path<String>) -> Json<String> {
h.into()
}

let mut app: Api<()> = Api::new()
// Add non-API-important routes or state by
// accessing axum's Router directly via inner_router
.inner_router(|f| f.route("/", get(root)))
// Add API-important routes with the route function
.route("/:hello", extract!(get(hello)));
let mut app: Router<()> = Router::new()
// Add non-API-important directly on the router
.route("/", get(root));
// Add API-important routes with the route macro
route!(app, "/:hello", get(hello));

```

### Step 3: Generate API

Generate the API file using the `generate_client` function on the `Api` struct. This generates the TypeScript file. You can specify a different `base` and a path, where the file should be generated to and with what name.

```rust,no_run
use gluer::Api;
Generate the API file using the `generate` macro. This generates the TypeScript file on macro expansion (compile time). You have to specify the `root directory` of your current project, normally `src`, a `path`, where the file should be generated to and with what name, and a different `base`, `""` means no different base.

let app: Api<()> = Api::new();
```rust
use gluer::generate;

app.generate_client("tests/api.ts", "");
// Make sure to change "tests" to "src" when copying this example
generate!("tests", "tests/api.ts", "");
```

### Step 4: Use the Wrapped Router

To start your server, get the inner router using the `into_router` function.

```rust,no_run
use gluer::Api;
#[tokio::main]
async fn main() {
let app: Api<()> = Api::new();
let listener = tokio::net::TcpListener::bind("127.0.0.1:8080")
.await
.unwrap();
axum::serve(listener, app.into_router()).await.unwrap();
}
```
And now you can just simply use the router to start your server or do different things, the API should be already generated by your LSP!

## Complete Example

Expand All @@ -188,9 +172,9 @@ Below is a complete example demonstrating the use of `gluer` with `axum`:
use axum::{
extract::{Path, Query},
routing::get,
Json,
Json, Router,
};
use gluer::{extract, metadata, Api};
use gluer::{generate, metadata, route};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;

Expand Down Expand Up @@ -265,16 +249,18 @@ type S = String;

#[tokio::main]
async fn main() {
let app: Api<()> = Api::new()
.route("/:p", extract!(get(fetch_root).post(add_root)))
.route("/char/:path/metadata/:path", extract!(get(get_alphabet)));
let mut _app: Router = Router::new();

route!(_app, "/:p", get(fetch_root).post(add_root));
route!(_app, "/char/:path/metadata/:path", get(get_alphabet));

app.generate_client("tests/api.ts", "").unwrap();
// Make sure to change "tests" to "src" when copying this example
generate!("tests", "tests/api.ts", "");

let _listener = tokio::net::TcpListener::bind("127.0.0.1:8080")
.await
.unwrap();
// starts the server, comment in and rename `_listener` to run it
// axum::serve(listener, app.into_router()).await.unwrap();
// axum::serve(listener, app).await.unwrap();
}
```
2 changes: 0 additions & 2 deletions macros/.gitignore

This file was deleted.

19 changes: 0 additions & 19 deletions macros/Cargo.toml

This file was deleted.

Loading

0 comments on commit e62d603

Please sign in to comment.