add answer entity and dto
This commit is contained in:
parent
26114a37b8
commit
ff4b5c7fd6
49
src/answer.rs
Normal file
49
src/answer.rs
Normal file
@ -0,0 +1,49 @@
|
||||
/// Contains struct definitions regarding answers
|
||||
use crate::*;
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
pub struct Answer {
|
||||
content: String,
|
||||
question_id: u8,
|
||||
}
|
||||
|
||||
impl Answer {
|
||||
pub fn _new(_id: u8, content: String, question_id: u8) -> Self {
|
||||
Answer {
|
||||
content,
|
||||
question_id,
|
||||
}
|
||||
}
|
||||
pub fn to_dto(&self, id: u8) -> AnswerDTO {
|
||||
AnswerDTO {
|
||||
id,
|
||||
content: self.content.clone(),
|
||||
question_id: self.question_id,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize, Clone, Debug)]
|
||||
pub struct AnswerDTO {
|
||||
id: u8,
|
||||
content: String,
|
||||
question_id: u8,
|
||||
}
|
||||
|
||||
/// Answer Data Transfer Object, a representation of the expected serialized JSON formated of answer regarding requests, responses, and our answer json file
|
||||
impl AnswerDTO {
|
||||
pub fn to_entity(&self) -> (u8, Answer) {
|
||||
(
|
||||
self.id,
|
||||
Answer {
|
||||
content: self.content.clone(),
|
||||
question_id: self.question_id,
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
impl IntoResponse for &AnswerDTO {
|
||||
fn into_response(self) -> Response {
|
||||
(StatusCode::OK, Json(&self)).into_response()
|
||||
}
|
||||
}
|
19
src/api.rs
19
src/api.rs
@ -1,5 +1,5 @@
|
||||
/// All API route handlers of the application
|
||||
use self::{question::QuestionDTO, store::Store};
|
||||
use self::{answer::AnswerDTO, question::QuestionDTO, store::Store};
|
||||
use crate::*;
|
||||
const DEFAULT_PAGE: usize = 0;
|
||||
const DEFAULT_PAGE_SIZE: usize = 10;
|
||||
@ -32,7 +32,11 @@ pub async fn read_questions(
|
||||
let page: usize = pagination.page.unwrap_or(DEFAULT_PAGE);
|
||||
let size: usize = pagination.size.unwrap_or(DEFAULT_PAGE_SIZE);
|
||||
let start: usize = page * size;
|
||||
(StatusCode::OK, Json(store.read().await.fetch_many(start, size))).into_response()
|
||||
(
|
||||
StatusCode::OK,
|
||||
Json(store.read().await.fetch_many(start, size)),
|
||||
)
|
||||
.into_response()
|
||||
}
|
||||
|
||||
/// Creates a new question
|
||||
@ -89,16 +93,19 @@ pub async fn delete_question(
|
||||
Err(e) => (StatusCode::NOT_FOUND, e).into_response(),
|
||||
}
|
||||
}
|
||||
/// Create an Answer
|
||||
/// Create an Answer - WIP
|
||||
/// # Parameters
|
||||
/// `answer_dto` Form URL encoded answer DTO
|
||||
/// # Returns
|
||||
pub async fn create_answer(State(_store): State<Arc<RwLock<Store>>> /*TODO */) -> Response {
|
||||
pub async fn create_answer(
|
||||
State(_store): State<Arc<RwLock<Store>>>,
|
||||
Form(_answer_dto): Form<AnswerDTO>,
|
||||
) -> Response {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct Pagination {
|
||||
pub struct Pagination {
|
||||
page: Option<usize>,
|
||||
size: Option<usize>,
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
mod answer;
|
||||
mod api;
|
||||
mod question;
|
||||
mod store;
|
||||
@ -6,7 +7,7 @@ use axum::{
|
||||
http::StatusCode,
|
||||
response::{IntoResponse, Response},
|
||||
routing::{delete, get, post, put},
|
||||
Json, Router,
|
||||
Form, Json, Router,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{
|
||||
|
17
src/store.rs
17
src/store.rs
@ -4,12 +4,13 @@
|
||||
use self::question::{Question, QuestionDTO};
|
||||
use crate::*;
|
||||
|
||||
const DB_PATH: &str = "./questions.json";
|
||||
const QUESTIONS_DB_PATH: &str = "./questions.json";
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Store {
|
||||
file: File,
|
||||
questions: HashMap<u8, Question>,
|
||||
// answers: HashMap<u8, Answer>, //WIP, add answers to store
|
||||
}
|
||||
|
||||
impl Store {
|
||||
@ -17,10 +18,13 @@ impl Store {
|
||||
// Otherwise we create questions.json.
|
||||
// JSON formatting and I/O errors possible here are semi-handled with a message, but ultimetly we will panic in those cases
|
||||
pub fn new() -> Self {
|
||||
let file: File = File::create_new(DB_PATH)
|
||||
let file: File = File::create_new(QUESTIONS_DB_PATH)
|
||||
.or_else(|e| {
|
||||
if e.kind() == ErrorKind::AlreadyExists {
|
||||
File::options().read(true).write(true).open(DB_PATH)
|
||||
File::options()
|
||||
.read(true)
|
||||
.write(true)
|
||||
.open(QUESTIONS_DB_PATH)
|
||||
} else {
|
||||
Err(e)
|
||||
}
|
||||
@ -89,7 +93,12 @@ impl Store {
|
||||
}
|
||||
//by nature of the hashmap, pagination does not follow id order
|
||||
pub fn fetch_many(&self, start: usize, size: usize) -> Vec<QuestionDTO> {
|
||||
self.questions.iter().map(|q|q.1.to_dto(*q.0)).skip(start).take(size).collect()
|
||||
self.questions
|
||||
.iter()
|
||||
.map(|q| q.1.to_dto(*q.0))
|
||||
.skip(start)
|
||||
.take(size)
|
||||
.collect()
|
||||
}
|
||||
pub fn update(&mut self, id: u8, question: Question) -> Result<Question, String> {
|
||||
if !self.questions.contains_key(&id) {
|
||||
|
Reference in New Issue
Block a user