use hyper::{StatusCode, Response, Body}; use hyper::header::HeaderValue; use mysql_async::{Conn, Pool}; use mysql_async::error::Error; use mysql_async::prelude::Queryable; enum ChannelType { Voice, Text, Undefined } impl ChannelType { fn from_i32(x: i32) -> ChannelType { match x { 1 => ChannelType::Voice, 2 => ChannelType::Text, _ => ChannelType::Undefined } } fn as_i32(&self) -> i32 { match self { ChannelType::Voice => 1, ChannelType::Text => 2, ChannelType::Undefined => 3, } } } struct Channel { id: i32, name: String, description: String, kind: ChannelType } impl Channel { fn from_tup(tup: (i32, String, String, i32)) -> Channel { Channel { id: tup.0, name: tup.1, description: tup.2, kind: ChannelType::from_i32(tup.3) } } fn as_json_str(&self) -> String { let mut base = String::from("{"); base.push_str(&format!("\"id\":{},", self.id)); base.push_str(&format!("\"name\":\"{}\",", self.name)); base.push_str(&format!("\"description\":\"{}\",", self.description)); base.push_str(&format!("\"kind\":{}}}", self.kind.as_i32())); return base; } } async fn get_channels_vec(conn: Conn) -> Result, Error> { let rows_db = conn.prep_exec(r"SELECT * FROM channels", ()).await?; let (_, rows) = rows_db.map_and_drop(|row| { let (id, name, desc, kind): (i32, String, String, i32) = mysql_async::from_row(row); Channel::from_tup((id, name, desc, kind)) }).await?; Ok(rows) } pub async fn list_channels(pool: &Pool, response: &mut Response) { if let Ok(conn) = pool.get_conn().await { match get_channels_vec(conn).await { Ok(chans) => { *response.status_mut() = StatusCode::OK; response.headers_mut().insert("Content-Type", HeaderValue::from_static("application/json")); let mut new_body = String::from("{\"channels\":["); for chan in chans.iter() { let s = format!("{},", chan.as_json_str()); new_body.push_str(&s); } if new_body.ends_with(',') {new_body.pop();} new_body.push_str("]}"); *response.body_mut() = Body::from(new_body); }, Err(_) => { *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; } } } }