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()
|
||||||
|
}
|
||||||
|
}
|
17
src/api.rs
17
src/api.rs
@ -1,5 +1,5 @@
|
|||||||
/// All API route handlers of the application
|
/// All API route handlers of the application
|
||||||
use self::{question::QuestionDTO, store::Store};
|
use self::{answer::AnswerDTO, question::QuestionDTO, store::Store};
|
||||||
use crate::*;
|
use crate::*;
|
||||||
const DEFAULT_PAGE: usize = 0;
|
const DEFAULT_PAGE: usize = 0;
|
||||||
const DEFAULT_PAGE_SIZE: usize = 10;
|
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 page: usize = pagination.page.unwrap_or(DEFAULT_PAGE);
|
||||||
let size: usize = pagination.size.unwrap_or(DEFAULT_PAGE_SIZE);
|
let size: usize = pagination.size.unwrap_or(DEFAULT_PAGE_SIZE);
|
||||||
let start: usize = 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
|
/// Creates a new question
|
||||||
@ -89,10 +93,14 @@ pub async fn delete_question(
|
|||||||
Err(e) => (StatusCode::NOT_FOUND, e).into_response(),
|
Err(e) => (StatusCode::NOT_FOUND, e).into_response(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Create an Answer
|
/// Create an Answer - WIP
|
||||||
/// # Parameters
|
/// # Parameters
|
||||||
|
/// `answer_dto` Form URL encoded answer DTO
|
||||||
/// # Returns
|
/// # 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!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,4 +109,3 @@ pub async fn create_answer(State(_store): State<Arc<RwLock<Store>>> /*TODO */) -
|
|||||||
page: Option<usize>,
|
page: Option<usize>,
|
||||||
size: Option<usize>,
|
size: Option<usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
mod answer;
|
||||||
mod api;
|
mod api;
|
||||||
mod question;
|
mod question;
|
||||||
mod store;
|
mod store;
|
||||||
@ -6,7 +7,7 @@ use axum::{
|
|||||||
http::StatusCode,
|
http::StatusCode,
|
||||||
response::{IntoResponse, Response},
|
response::{IntoResponse, Response},
|
||||||
routing::{delete, get, post, put},
|
routing::{delete, get, post, put},
|
||||||
Json, Router,
|
Form, Json, Router,
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::{
|
use std::{
|
||||||
|
17
src/store.rs
17
src/store.rs
@ -4,12 +4,13 @@
|
|||||||
use self::question::{Question, QuestionDTO};
|
use self::question::{Question, QuestionDTO};
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
const DB_PATH: &str = "./questions.json";
|
const QUESTIONS_DB_PATH: &str = "./questions.json";
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Store {
|
pub struct Store {
|
||||||
file: File,
|
file: File,
|
||||||
questions: HashMap<u8, Question>,
|
questions: HashMap<u8, Question>,
|
||||||
|
// answers: HashMap<u8, Answer>, //WIP, add answers to store
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Store {
|
impl Store {
|
||||||
@ -17,10 +18,13 @@ impl Store {
|
|||||||
// Otherwise we create questions.json.
|
// 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
|
// 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 {
|
pub fn new() -> Self {
|
||||||
let file: File = File::create_new(DB_PATH)
|
let file: File = File::create_new(QUESTIONS_DB_PATH)
|
||||||
.or_else(|e| {
|
.or_else(|e| {
|
||||||
if e.kind() == ErrorKind::AlreadyExists {
|
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 {
|
} else {
|
||||||
Err(e)
|
Err(e)
|
||||||
}
|
}
|
||||||
@ -89,7 +93,12 @@ impl Store {
|
|||||||
}
|
}
|
||||||
//by nature of the hashmap, pagination does not follow id order
|
//by nature of the hashmap, pagination does not follow id order
|
||||||
pub fn fetch_many(&self, start: usize, size: usize) -> Vec<QuestionDTO> {
|
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> {
|
pub fn update(&mut self, id: u8, question: Question) -> Result<Question, String> {
|
||||||
if !self.questions.contains_key(&id) {
|
if !self.questions.contains_key(&id) {
|
||||||
|
Reference in New Issue
Block a user