Sample layout with test data

This commit is contained in:
Candifloss 2026-04-22 14:35:44 +05:30
parent 43472a2fc3
commit 2f597030b5
4 changed files with 153 additions and 2 deletions

57
src/db.rs Normal file
View File

@ -0,0 +1,57 @@
use rusqlite::{Connection, Result};
use std::sync::Mutex;
use rusqlite::types::Value;
pub struct Db {
conn: Mutex<Connection>,
}
impl Db {
pub fn open(path: &str) -> Result<Self> {
Ok(Self {
conn: Mutex::new(Connection::open(path)?),
})
}
pub fn get_users(&self) -> Result<(Vec<String>, Vec<Vec<String>>)> {
let conn = self.conn.lock().unwrap();
let mut stmt = conn.prepare("SELECT * FROM users")?;
let columns = stmt
.column_names()
.iter()
.map(|s| s.to_string())
.collect::<Vec<_>>();
let col_count = stmt.column_count();
let rows_iter = stmt.query_map([], move |row| {
let mut r = Vec::new();
for i in 0..col_count {
let val: Value = row.get(i)?;
let s = match val {
Value::Null => "<null>".to_string(),
Value::Integer(i) => i.to_string(),
Value::Real(f) => f.to_string(),
Value::Text(t) => t, // already String
Value::Blob(_) => "<blob>".to_string(),
};
r.push(s);
}
Ok(r)
})?;
let mut rows = Vec::new();
for r in rows_iter {
rows.push(r?);
}
Ok((columns, rows))
}
}

View File

@ -1,3 +1,36 @@
fn main() {
println!("Hello, world!");
use axum::{routing::get, Router};
use clap::Parser;
use std::sync::Arc;
use tokio::net::TcpListener;
mod db;
mod routes;
use db::Db;
#[derive(Parser)]
struct Args {
#[arg(long)]
db: String,
}
#[tokio::main]
async fn main() {
let args = Args::parse();
let db = Arc::new(Db::open(&args.db).expect("db open failed"));
let app = Router::new()
.route("/", get(routes::index))
.with_state(db);
let listener = TcpListener::bind("127.0.0.1:8040")
.await
.unwrap();
println!("http://127.0.0.1:8040");
axum::serve(listener, app)
.await
.unwrap();
}

29
src/routes.rs Normal file
View File

@ -0,0 +1,29 @@
use askama::Template; // REQUIRED
use axum::{
extract::State,
response::Html,
};
use std::sync::Arc;
use crate::db::Db;
#[derive(Template)]
#[template(path = "table.html")]
pub struct TableTemplate {
pub table_name: String,
pub columns: Vec<String>,
pub rows: Vec<Vec<String>>,
}
pub async fn index(State(db): State<Arc<Db>>) -> Html<String> {
let (columns, rows) = db.get_users().unwrap();
let tmpl = TableTemplate {
table_name: "users".into(),
columns,
rows,
};
Html(tmpl.render().unwrap())
}

32
templates/table.html Normal file
View File

@ -0,0 +1,32 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>{{ table_name }}</title>
</head>
<body>
<h1>{{ table_name }}</h1>
<table border="1" cellspacing="0" cellpadding="4">
<thead>
<tr>
{% for col in columns %}
<th>{{ col }}</th>
{% endfor %}
</tr>
</thead>
<tbody>
{% for row in rows %}
<tr>
{% for cell in row %}
<td>{{ cell }}</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
</body>
</html>