Clean up 'TemplateContext', handle character visibility.
This commit is contained in:
parent
10d5f30e5a
commit
8638c1d598
|
@ -1,17 +1,40 @@
|
||||||
|
use crate::models::users::User;
|
||||||
use crate::schema::characters;
|
use crate::schema::characters;
|
||||||
use rocket::http::RawStr;
|
|
||||||
use rocket::request::{self, FromParam, FromRequest, Request};
|
|
||||||
use serde_derive::Serialize;
|
use serde_derive::Serialize;
|
||||||
|
|
||||||
|
/// An entry that appears in a user's character list. Properties are
|
||||||
|
/// in order of table columns.
|
||||||
#[derive(Serialize, Debug, Queryable)]
|
#[derive(Serialize, Debug, Queryable)]
|
||||||
pub struct CharacterEntry {
|
pub struct CharacterEntry {
|
||||||
pub id: i32,
|
pub id: i32,
|
||||||
pub user_id: i32,
|
pub user_id: i32,
|
||||||
pub viewable: bool,
|
pub viewable: bool,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
//TODO don't need to carry around character data for this.
|
||||||
pub data: Option<Vec<u8>>,
|
pub data: Option<Vec<u8>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl CharacterEntry {
|
||||||
|
/// Transform to an Option that holds the character, if the
|
||||||
|
/// character is viewable to a potentially existing user. A
|
||||||
|
/// character is "visible" if the public viewable property is set
|
||||||
|
/// to true, or the user is the owner of the character. Consumes
|
||||||
|
/// self.
|
||||||
|
pub fn as_visible_for(self, user: Option<&User>) -> Option<CharacterEntry> {
|
||||||
|
let character_is_visible = |c: CharacterEntry| {
|
||||||
|
if c.viewable || user.map(|u| u.id) == Some(c.user_id) {
|
||||||
|
Some(c)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Some(self).and_then(character_is_visible)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Represents insert of a new character into the database. Property
|
||||||
|
/// names correspond to columns.
|
||||||
#[derive(Insertable)]
|
#[derive(Insertable)]
|
||||||
#[table_name = "characters"]
|
#[table_name = "characters"]
|
||||||
pub struct NewCharacter<'a> {
|
pub struct NewCharacter<'a> {
|
||||||
|
|
|
@ -1,12 +1,8 @@
|
||||||
use crate::db::{Dao, TenebrousDbConn};
|
use crate::db::{Dao, TenebrousDbConn};
|
||||||
use crate::errors::Error;
|
use crate::errors::Error;
|
||||||
use crate::models::{
|
use crate::models::users::User;
|
||||||
characters::{CharacterEntry, NewCharacter},
|
|
||||||
users::User,
|
|
||||||
};
|
|
||||||
use rocket::response::Redirect;
|
use rocket::response::Redirect;
|
||||||
use rocket_contrib::templates::Template;
|
use rocket_contrib::templates::Template;
|
||||||
use serde_derive::Serialize;
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
pub(crate) fn routes() -> Vec<rocket::Route> {
|
pub(crate) fn routes() -> Vec<rocket::Route> {
|
||||||
|
@ -18,23 +14,19 @@ pub(crate) fn routes() -> Vec<rocket::Route> {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO make private -- currently is referenced in homepage route.
|
|
||||||
//or move to common place.
|
|
||||||
#[derive(Serialize)]
|
|
||||||
pub struct TemplateContext<'a> {
|
|
||||||
pub characters: Vec<CharacterEntry>,
|
|
||||||
pub user: &'a User,
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO should return result based on whether or not character is publicly viewable.
|
|
||||||
#[get("/<username>/<character_id>")]
|
#[get("/<username>/<character_id>")]
|
||||||
fn view_character(
|
fn view_character(
|
||||||
character_id: i32,
|
character_id: i32,
|
||||||
username: String,
|
username: String,
|
||||||
conn: TenebrousDbConn,
|
conn: TenebrousDbConn,
|
||||||
|
logged_in_user: Option<&User>,
|
||||||
) -> Result<Template, Error> {
|
) -> Result<Template, Error> {
|
||||||
let user = conn.load_user(&username)?.ok_or(Error::NotFound)?;
|
let user = conn.load_user(&username)?.ok_or(Error::NotFound)?;
|
||||||
let character = conn.load_character(character_id)?.ok_or(Error::NotFound)?;
|
|
||||||
|
let character = conn
|
||||||
|
.load_character(character_id)?
|
||||||
|
.and_then(|c| c.as_visible_for(logged_in_user))
|
||||||
|
.ok_or(Error::NotFound)?;
|
||||||
|
|
||||||
let mut context = HashMap::new();
|
let mut context = HashMap::new();
|
||||||
context.insert("name", character.name);
|
context.insert("name", character.name);
|
||||||
|
|
|
@ -3,18 +3,25 @@ use crate::errors::Error;
|
||||||
use crate::models::{characters::CharacterEntry, users::User};
|
use crate::models::{characters::CharacterEntry, users::User};
|
||||||
use rocket::response::Redirect;
|
use rocket::response::Redirect;
|
||||||
use rocket_contrib::templates::Template;
|
use rocket_contrib::templates::Template;
|
||||||
|
use serde_derive::Serialize;
|
||||||
|
|
||||||
pub fn routes() -> Vec<rocket::Route> {
|
pub fn routes() -> Vec<rocket::Route> {
|
||||||
routes![index, user_index]
|
routes![index, user_index]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Information to display to the user on their home page.
|
||||||
|
#[derive(Serialize)]
|
||||||
|
pub struct UserHomeContext<'a> {
|
||||||
|
pub characters: &'a [CharacterEntry],
|
||||||
|
pub user: &'a User,
|
||||||
|
}
|
||||||
|
|
||||||
#[get("/")]
|
#[get("/")]
|
||||||
fn user_index(user: &User, conn: TenebrousDbConn) -> Result<Template, Error> {
|
fn user_index(user: &User, conn: TenebrousDbConn) -> Result<Template, Error> {
|
||||||
use crate::routes::characters::TemplateContext;
|
|
||||||
let characters = conn.load_character_list(user.id)?;
|
let characters = conn.load_character_list(user.id)?;
|
||||||
|
|
||||||
let context = TemplateContext {
|
let context = UserHomeContext {
|
||||||
characters: characters,
|
characters: &characters,
|
||||||
user: user,
|
user: user,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue