features, cleanup and bug fixes #26
1 changed files with 61 additions and 6 deletions
impl Hash for JobOffer so a future edit dialog can detect concurrent modifications
commit
4e78d960fa
|
|
@ -1,6 +1,7 @@
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::collections::{BTreeMap, HashMap};
|
use std::collections::{BTreeMap, HashMap};
|
||||||
use std::fmt::Formatter;
|
use std::fmt::Formatter;
|
||||||
|
use std::hash::{Hash, Hasher};
|
||||||
use std::io::ErrorKind;
|
use std::io::ErrorKind;
|
||||||
use std::net::IpAddr;
|
use std::net::IpAddr;
|
||||||
use std::ops::{Add, Deref};
|
use std::ops::{Add, Deref};
|
||||||
|
|
@ -18,7 +19,7 @@ use rand::distributions::DistString;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use tempfile::NamedTempFile;
|
use tempfile::NamedTempFile;
|
||||||
use tokio::sync::{Mutex, RwLock, RwLockMappedWriteGuard, RwLockReadGuard, RwLockWriteGuard};
|
use tokio::sync::{Mutex, RwLock, RwLockMappedWriteGuard, RwLockReadGuard, RwLockWriteGuard};
|
||||||
use toml::value::Datetime;
|
use toml::value::{Datetime, Offset};
|
||||||
|
|
||||||
use crate::auth::User;
|
use crate::auth::User;
|
||||||
use crate::error::PresentationError;
|
use crate::error::PresentationError;
|
||||||
|
|
@ -185,7 +186,7 @@ pub(crate) fn job_data<'i, I: Iterator<Item = (&'i str, &'i JobOffer<PathBuf>)>>
|
||||||
data
|
data
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(serde::Serialize, serde::Deserialize, Debug)]
|
#[derive(serde::Serialize, serde::Deserialize, Debug, Hash)]
|
||||||
pub(crate) struct Attachment<Location> {
|
pub(crate) struct Attachment<Location> {
|
||||||
// The title for this attachment as displayed
|
// The title for this attachment as displayed
|
||||||
pub(crate) title: String,
|
pub(crate) title: String,
|
||||||
|
|
@ -196,20 +197,20 @@ pub(crate) struct Attachment<Location> {
|
||||||
pub(crate) attachment_location: Location,
|
pub(crate) attachment_location: Location,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
|
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, Hash)]
|
||||||
pub(crate) struct Link {
|
pub(crate) struct Link {
|
||||||
pub(crate) title: String,
|
pub(crate) title: String,
|
||||||
pub(crate) destination: String,
|
pub(crate) destination: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
|
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, Hash)]
|
||||||
#[serde(tag = "type")]
|
#[serde(tag = "type")]
|
||||||
pub enum ConfirmationStatus {
|
pub enum ConfirmationStatus {
|
||||||
AwaitingConfirmation { token: String },
|
AwaitingConfirmation { token: String },
|
||||||
Confirmed,
|
Confirmed,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
|
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, Hash)]
|
||||||
pub enum ReviewStatus {
|
pub enum ReviewStatus {
|
||||||
/// Has yet to be reviewed
|
/// Has yet to be reviewed
|
||||||
AwaitingReview,
|
AwaitingReview,
|
||||||
|
|
@ -219,7 +220,7 @@ pub enum ReviewStatus {
|
||||||
UnPublished,
|
UnPublished,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
|
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, Hash)]
|
||||||
pub struct JobOfferStatus {
|
pub struct JobOfferStatus {
|
||||||
review_status: ReviewStatus,
|
review_status: ReviewStatus,
|
||||||
confirmation_status: ConfirmationStatus,
|
confirmation_status: ConfirmationStatus,
|
||||||
|
|
@ -295,6 +296,14 @@ impl JobOfferStatus {
|
||||||
#[serde(try_from = "toml::value::Datetime", into = "toml::value::Datetime")]
|
#[serde(try_from = "toml::value::Datetime", into = "toml::value::Datetime")]
|
||||||
pub(crate) struct Date(pub(crate) toml::value::Date);
|
pub(crate) struct Date(pub(crate) toml::value::Date);
|
||||||
|
|
||||||
|
impl Hash for Date {
|
||||||
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
|
self.0.day.hash(state);
|
||||||
|
self.0.month.hash(state);
|
||||||
|
self.0.year.hash(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl std::fmt::Debug for Date {
|
impl std::fmt::Debug for Date {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
f.debug_struct("Date")
|
f.debug_struct("Date")
|
||||||
|
|
@ -347,6 +356,52 @@ pub struct JobOffer<AttachmentLocation> {
|
||||||
pub(crate) links: Vec<Link>,
|
pub(crate) links: Vec<Link>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Hash for JobOffer<PathBuf> {
|
||||||
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
|
self.title.hash(state);
|
||||||
|
self.offering_party.hash(state);
|
||||||
|
self.public_contact_info.hash(state);
|
||||||
|
// TODO date_of_submission
|
||||||
|
if let Some(date) = &self.date_of_submission.date {
|
||||||
|
1.hash(state);
|
||||||
|
date.day.hash(state);
|
||||||
|
date.month.hash(state);
|
||||||
|
date.year.hash(state);
|
||||||
|
} else {
|
||||||
|
0.hash(state);
|
||||||
|
}
|
||||||
|
if let Some(time) = &self.date_of_submission.time {
|
||||||
|
1.hash(state);
|
||||||
|
time.hour.hash(state);
|
||||||
|
time.minute.hash(state);
|
||||||
|
time.second.hash(state);
|
||||||
|
time.nanosecond.hash(state);
|
||||||
|
} else {
|
||||||
|
0.hash(state);
|
||||||
|
}
|
||||||
|
if let Some(offset) = &self.date_of_submission.offset {
|
||||||
|
match offset {
|
||||||
|
Offset::Z => {
|
||||||
|
1.hash(state);
|
||||||
|
}
|
||||||
|
Offset::Custom { hours, minutes } => {
|
||||||
|
2.hash(state);
|
||||||
|
hours.hash(state);
|
||||||
|
minutes.hash(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
0.hash(state);
|
||||||
|
}
|
||||||
|
self.date_of_expiry.hash(state);
|
||||||
|
self.permanent.hash(state);
|
||||||
|
self.contact_info.hash(state);
|
||||||
|
self.status.hash(state);
|
||||||
|
self.attachments.hash(state);
|
||||||
|
self.links.hash(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Deref for JobOffer<PathBuf> {
|
impl Deref for JobOffer<PathBuf> {
|
||||||
type Target = JobOfferStatus;
|
type Target = JobOfferStatus;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue