Files
core/test/performance/fixtures/api-json/runtime-peer.rs
T
2026-11-03 03:32:07 +00:00

247 lines
6.9 KiB
Rust

use dever_runtime::api;
use dever_runtime::application::Session;
use dever_runtime::auth;
use dever_runtime::config::RuntimeProfile;
use dever_runtime::http::{Request, Response};
use dever_runtime::wire::decode::{self, Fields, Reader};
use dever_runtime::wire::{Encoded, Encoder};
use dever_runtime::{lifecycle, task};
#[derive(Default)]
struct Row {
id: i64,
text: String,
weight: f64,
note: Option<String>,
}
impl Fields for Row {
fn count(&self) -> usize {
4
}
fn index(&self, name: &str) -> Result<usize, String> {
match name {
"id" => Ok(0),
"text" => Ok(1),
"weight" => Ok(2),
"note" => Ok(3),
_ => Err("unknown wire record field".into()),
}
}
fn required(&self, index: usize) -> bool {
index != 3
}
fn read(&mut self, index: usize, reader: &mut Reader<'_, '_>) -> Result<(), String> {
match index {
0 => self.id = reader.int()?,
1 => self.text = reader.text()?.into_owned(),
2 => self.weight = reader.float()?,
3 => {
reader.nullable(&mut |reader| {
self.note = Some(reader.text()?.into_owned());
Ok(())
})?;
}
_ => return Err("invalid wire field index".into()),
}
Ok(())
}
}
#[derive(Default)]
struct Payload {
rows: Vec<Row>,
raw: Option<Encoded>,
}
impl Fields for Payload {
fn count(&self) -> usize {
2
}
fn index(&self, name: &str) -> Result<usize, String> {
match name {
"rows" => Ok(0),
"raw" => Ok(1),
_ => Err("unknown wire record field".into()),
}
}
fn required(&self, _: usize) -> bool {
true
}
fn read(&mut self, index: usize, reader: &mut Reader<'_, '_>) -> Result<(), String> {
match index {
0 => reader.list(&mut |reader| {
let mut row = Row::default();
reader.record(&mut row)?;
self.rows.push(row);
Ok(())
}),
1 => {
self.raw = Some(reader.json()?);
Ok(())
}
_ => Err("invalid wire field index".into()),
}
}
}
impl Payload {
fn encode(self) -> Result<Encoded, String> {
let mut encoder = Encoder::default();
encoder.compiled_record(2, |encoder| {
encoder.compiled_key("\"rows\":")?;
encoder.begin_array()?;
for row in self.rows {
encoder.compiled_record(4, |encoder| {
encoder.compiled_key("\"id\":")?;
encoder.int(row.id)?;
encoder.compiled_key(",\"text\":")?;
encoder.text(&row.text)?;
encoder.compiled_key(",\"weight\":")?;
encoder.float(row.weight)?;
encoder.compiled_key(",\"note\":")?;
match row.note {
Some(note) => encoder.text(&note),
None => encoder.null(),
}
})?;
}
encoder.end()?;
encoder.compiled_key(",\"raw\":")?;
encoder.encoded(&self.raw.ok_or("missing required wire field")?)
})?;
encoder.finish()
}
}
enum Value {
Typed(Payload),
Raw(Encoded),
}
struct Arguments {
typed: bool,
value: Option<Value>,
}
impl Fields for Arguments {
fn count(&self) -> usize {
1
}
fn index(&self, name: &str) -> Result<usize, String> {
if name == if self.typed { "payload" } else { "source" } {
Ok(0)
} else {
Err("unknown wire record field".into())
}
}
fn required(&self, _: usize) -> bool {
true
}
fn read(&mut self, _: usize, reader: &mut Reader<'_, '_>) -> Result<(), String> {
self.value = Some(if self.typed {
let mut payload = Payload::default();
reader.record(&mut payload)?;
Value::Typed(payload)
} else {
Value::Raw(reader.json()?)
});
Ok(())
}
}
async fn call(mut request: Request, typed: bool) -> Response {
if let Err(error) = auth::require_components(&[], &[]).await {
return api::auth_error(error);
}
if let Err(error) = api::upload::read_body(&mut request).await {
return api::invalid_input(error);
}
let body = match api::Inputs::json_body(&request) {
Ok(body) => body,
Err(error) => return api::invalid_input(error),
};
let mut arguments = Arguments { typed, value: None };
if let Err(error) = decode::read(body, &mut |reader| reader.record(&mut arguments)) {
return api::invalid_input(api::InputError(error));
}
let encoded = match arguments.value {
Some(Value::Typed(payload)) => payload.encode(),
Some(Value::Raw(value)) => Ok(value),
None => Err("missing required wire field".into()),
};
match encoded {
Ok(value) => {
if api::commit_response_metadata().is_err() {
return api::internal_error();
}
api::success(value)
}
Err(_) => api::internal_error(),
}
}
async fn route(request: Request) -> Result<Response, String> {
let typed = match request.target.split('?').next().unwrap_or("") {
"/benchmark/echo/echo" => true,
"/benchmark/echo/raw" => false,
_ => return Ok(api::not_found()),
};
if request.method != "POST" {
return Ok(api::method_not_allowed(&["POST"]));
}
let prepared = match auth::prepare(&[], &request, true) {
Ok(prepared) => prepared,
Err(error) => return Ok(api::auth_error(error)),
};
let identity = prepared.claims().map(|claims| auth::Identity {
id: claims.subject.clone(),
user_id: None,
tenant_id: None,
});
Ok(
match auth::scope(prepared, identity, call(request, typed)).await {
Ok(response) => response,
Err(error) => api::auth_error(error),
},
)
}
fn main() -> Result<(), String> {
let session = Session::load(
RuntimeProfile {
sqlite: true,
postgres: false,
},
&[(None, "benchmark", false)],
&[],
)?;
session.initialize_authorization(false)?;
let cleanup = session.clone();
task::run_entry_with_typed_cleanup(
task::RuntimeConfig::default(),
session.clone().scope(async move {
session
.databases()
.prepare()
.await
.map_err(|error| error.to_string())?;
lifecycle::configure(true, false)?;
lifecycle::run(api::serve(route)).await
}),
|result| async move {
let closed = cleanup.close().await;
result.and(closed)
},
)
}