Examples in Rust
Rust examples using Plate-Link resolve endpoint
These examples call:
GET /{plateId}/resolve/{id}and redirect from your Rust server.
actix-web
use actix_web::{get, web, App, HttpRequest, HttpResponse, HttpServer, Responder};
use serde::Deserialize;
const LINK_BASE: &str = "https://link.example.com";
const PLATE_ID: &str = "1";
#[derive(Deserialize)]
struct ResolveEnvelope {
data: ResolveData,
}
#[derive(Deserialize)]
struct ResolveData {
destination: String,
}
#[get("/u/{id}/{tail:.*}")]
async fn redirect(path: web::Path<(String, String)>, req: HttpRequest) -> impl Responder {
let (id, tail) = path.into_inner();
let query = req.query_string();
let mut resolve = format!("{}/{}/resolve/{}", LINK_BASE, PLATE_ID, id);
if !tail.is_empty() {
resolve.push('/');
resolve.push_str(&tail);
}
if !query.is_empty() {
resolve.push('?');
resolve.push_str(query);
}
let response = match reqwest::get(resolve).await {
Ok(r) => r,
Err(_) => return HttpResponse::BadGateway().body("resolve failed"),
};
if !response.status().is_success() {
return HttpResponse::build(response.status()).body("link not found");
}
let payload: ResolveEnvelope = match response.json().await {
Ok(v) => v,
Err(_) => return HttpResponse::BadGateway().body("invalid resolve payload"),
};
HttpResponse::TemporaryRedirect()
.append_header(("Location", payload.data.destination))
.finish()
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| App::new().service(redirect))
.bind(("127.0.0.1", 8080))?
.run()
.await
}Rocket
#[macro_use]
extern crate rocket;
use rocket::response::Redirect;
use serde::Deserialize;
const LINK_BASE: &str = "https://link.example.com";
const PLATE_ID: &str = "1";
#[derive(Deserialize)]
struct ResolveEnvelope {
data: ResolveData,
}
#[derive(Deserialize)]
struct ResolveData {
destination: String,
}
#[get("/u/<id>/<tail..>?<q..>")]
async fn redirect(id: &str, tail: std::path::PathBuf, q: Option<String>) -> Result<Redirect, rocket::http::Status> {
let mut resolve = format!("{}/{}/resolve/{}", LINK_BASE, PLATE_ID, id);
if !tail.as_os_str().is_empty() {
resolve.push('/');
resolve.push_str(&tail.to_string_lossy());
}
if let Some(query) = q {
if !query.is_empty() {
resolve.push('?');
resolve.push_str(&query);
}
}
let response = reqwest::get(resolve)
.await
.map_err(|_| rocket::http::Status::BadGateway)?;
if !response.status().is_success() {
return Err(rocket::http::Status::NotFound);
}
let payload: ResolveEnvelope = response
.json()
.await
.map_err(|_| rocket::http::Status::BadGateway)?;
Ok(Redirect::temporary(payload.data.destination))
}
#[launch]
fn rocket() -> _ {
rocket::build().mount("/", routes![redirect])
}