claptest and rest api demo
cargo devel CI / cargo CI (push) Successful in 2m1s
Details
cargo devel CI / cargo CI (push) Successful in 2m1s
Details
This commit is contained in:
parent
1e68268d53
commit
a7ce0cc375
File diff suppressed because it is too large
Load Diff
|
@ -17,11 +17,14 @@ members = [
|
||||||
"members/mpsc",
|
"members/mpsc",
|
||||||
"members/mpsc-full",
|
"members/mpsc-full",
|
||||||
"members/echargs",
|
"members/echargs",
|
||||||
|
"members/claptest",
|
||||||
|
"members/rest",
|
||||||
]
|
]
|
||||||
default-members = [
|
default-members = [
|
||||||
".",
|
".",
|
||||||
"members/echargs",
|
"members/echargs",
|
||||||
"members/revsqrt",
|
"members/revsqrt",
|
||||||
|
"members/claptest",
|
||||||
"members/mpsc",
|
"members/mpsc",
|
||||||
"members/mpsc-full",
|
"members/mpsc-full",
|
||||||
"members/criterion-demo",
|
"members/criterion-demo",
|
||||||
|
@ -36,6 +39,7 @@ default-members = [
|
||||||
"members/tokio-send-sync",
|
"members/tokio-send-sync",
|
||||||
"members/matchmatchmatch",
|
"members/matchmatchmatch",
|
||||||
"members/future_stream",
|
"members/future_stream",
|
||||||
|
"members/rest",
|
||||||
]
|
]
|
||||||
publish = false
|
publish = false
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
[package]
|
||||||
|
name = "claptest"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
clap = { version = "4.5.2", features = ["derive"] }
|
|
@ -0,0 +1,13 @@
|
||||||
|
use clap::Parser;
|
||||||
|
#[derive(Parser, Debug)]
|
||||||
|
#[clap(author, version, about, long_about = None)]
|
||||||
|
pub struct Args {
|
||||||
|
/// important list of strings
|
||||||
|
#[arg(short, long, value_name = "String",num_args(0..), name="string")]
|
||||||
|
pub strings: Vec<String>,
|
||||||
|
}
|
||||||
|
fn main() {
|
||||||
|
println!("Hello, world!");
|
||||||
|
let args = Args::parse();
|
||||||
|
dbg!(args.strings);
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
[package]
|
||||||
|
name = "rest"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
libpt = { version = "0.4.2", features = ["log"] }
|
||||||
|
serde = { workspace = true, features = ["serde_derive"] }
|
||||||
|
serde_json.workspace = true
|
||||||
|
tokio = { workspace = true, features = ["full"] }
|
||||||
|
warp = "0.3.6"
|
|
@ -0,0 +1,16 @@
|
||||||
|
use libpt::log::{debug, info};
|
||||||
|
|
||||||
|
mod routes;
|
||||||
|
use routes::*;
|
||||||
|
mod store;
|
||||||
|
use store::*;
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
async fn main() {
|
||||||
|
libpt::log::Logger::build_mini(Some(libpt::log::Level::DEBUG)).expect("could not init logger");
|
||||||
|
let store = Store::new();
|
||||||
|
debug!("spawning data_processing task: {store:#?}");
|
||||||
|
tokio::spawn(data_processing(store.clone()));
|
||||||
|
info!("starting webserver");
|
||||||
|
warp::serve(routes(store)).run(([127, 0, 0, 1], 3030)).await;
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
use std::convert::Infallible;
|
||||||
|
|
||||||
|
use libpt::log::info;
|
||||||
|
use warp::{Filter, Rejection, Reply};
|
||||||
|
|
||||||
|
use crate::{Item, Store};
|
||||||
|
|
||||||
|
pub fn with_store(store: Store) -> impl Filter<Extract = (Store,), Error = Infallible> + Clone {
|
||||||
|
warp::any().map(move || store.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn routes(store: Store) -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone {
|
||||||
|
get_store(store.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
// GET /api/v1/store
|
||||||
|
pub fn get_store(store: Store) -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone {
|
||||||
|
warp::path!("api" / "v1" / "store")
|
||||||
|
.and(warp::get())
|
||||||
|
.and(with_store(store))
|
||||||
|
// .and(warp::body::content_length_limit(2 << 13))
|
||||||
|
.then(|store: Store| async move {
|
||||||
|
info!("GET /api/v1/store");
|
||||||
|
warp::reply::json(&store.get().await)
|
||||||
|
})
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
use std::{collections::VecDeque, sync::Arc};
|
||||||
|
use serde::Deserialize;
|
||||||
|
use tokio::sync::Mutex;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct Store {
|
||||||
|
inner: Arc<Mutex<VecDeque<Item>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type Item = serde_json::Value;
|
||||||
|
|
||||||
|
impl Store {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
inner: Arc::new(Mutex::new(
|
||||||
|
vec![
|
||||||
|
serde_json::json!({"foo": "bar", "value": 0}),
|
||||||
|
serde_json::json!({"foo": "bar", "value": 1}),
|
||||||
|
serde_json::json!({"foo": "bar", "value": 2}),
|
||||||
|
]
|
||||||
|
.into(),
|
||||||
|
)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub async fn add(&self, item: Item) {
|
||||||
|
let mut store = self.inner.lock().await;
|
||||||
|
if store.len() > 10 {
|
||||||
|
store.pop_front().unwrap();
|
||||||
|
}
|
||||||
|
store.push_back(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get(&self) -> Vec<Item> {
|
||||||
|
let store = self.inner.lock().await;
|
||||||
|
store.clone().into_iter().collect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn data_processing(store: Store) {
|
||||||
|
let mut iter = 3;
|
||||||
|
loop {
|
||||||
|
let msg = serde_json::json!({"foo": "bar", "value": iter});
|
||||||
|
store.add(msg).await;
|
||||||
|
iter += 1;
|
||||||
|
tokio::time::sleep(tokio::time::Duration::from_millis(1000)).await;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue