Initial commit

This commit is contained in:
Franklin 2023-03-14 20:57:57 -04:00
commit c6b524d7b1
21 changed files with 2020 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/target

1519
Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

20
Cargo.toml Normal file
View File

@ -0,0 +1,20 @@
[package]
name = "jl-types"
version = "0.1.0"
edition = "2021"
[lib]
[dependencies]
chrono = { version = "0.4.23", features = [ "serde" ] }
chrono-tz = "0.8"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0.88"
uuid = { version = "1.3.0", features = ["v4", "fast-rng", "macro-diagnostics", "serde"] }
format_num = "0.1.0"
sqlx = { version = "0.6.0", features = [ "runtime-tokio-rustls", "postgres", "chrono", "uuid" ] }
bincode = "1.3.3"
[features]
#sqlx = ["dep:sqlx"]
#wasm = ["uuid/js"]

24
src/domain/agent.rs Normal file
View File

@ -0,0 +1,24 @@
use chrono::{DateTime, Utc};
use serde::{Serialize, Deserialize};
use uuid::Uuid;
use super::credential::CredentialType;
#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct Agent {
pub id: Uuid,
#[serde(rename = "fullName")]
pub full_name: String,
pub credential: String,
#[serde(rename = "credentialType")]
pub credential_type: CredentialType,
#[serde(rename = "timeCreated")]
pub time_created: DateTime<Utc>,
#[serde(rename = "lastUpdated")]
pub last_updated: DateTime<Utc>,
}

View File

@ -0,0 +1,31 @@
use sqlx::{Postgres, postgres::{PgValueRef, PgTypeInfo, PgArgumentBuffer}, error::BoxDynError, encode::IsNull};
use super::CredentialType;
use std::str::FromStr;
impl sqlx::Encode<'_, Postgres> for CredentialType {
fn encode_by_ref(&self, buf: &mut PgArgumentBuffer) -> IsNull {
let binding = self.to_string();
<&str as sqlx::Encode<Postgres>>::encode(&binding, buf)
}
}
impl sqlx::Decode<'_, Postgres> for CredentialType {
fn decode(value: PgValueRef<'_>) -> Result<Self, BoxDynError> {
let column = value.as_str()?;
match Self::from_str(column) {
Ok(listing_state) => Ok(listing_state),
Err(error) => Err(Box::new(error)),
}
}
}
impl sqlx::Type<Postgres> for CredentialType {
fn type_info() -> PgTypeInfo {
PgTypeInfo::with_name("VARCHAR")
}
fn compatible(ty: &<Postgres as sqlx::Database>::TypeInfo) -> bool {
*ty == Self::type_info()
}
}

View File

@ -0,0 +1,35 @@
#[cfg(feature = "sqlx")]
pub mod impls;
use std::{fmt::Display, str::FromStr};
use serde::{Deserialize, Serialize};
use super::error::Error;
#[derive(Serialize, Deserialize, Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum CredentialType {
#[default]
PhoneNumber,
Email,
}
impl Display for CredentialType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
CredentialType::PhoneNumber => write!(f, "PhoneNumber"),
CredentialType::Email => write!(f, "Email"),
}
}
}
impl FromStr for CredentialType {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"PhoneNumber" => Ok(Self::PhoneNumber),
"Email" => Ok(Self::Email),
_ => Err(Error::Parsing),
}
}
}

21
src/domain/error.rs Normal file
View File

@ -0,0 +1,21 @@
use std::fmt::Display;
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum Error {
Parsing
}
impl Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Error::Parsing => write!(f, "Parsing Error"),
}
}
}
impl std::error::Error for Error {
}

10
src/domain/location.rs Normal file
View File

@ -0,0 +1,10 @@
use serde::{Serialize, Deserialize};
use uuid::Uuid;
#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct Location {
pub id: Uuid,
pub city: String,
pub district: String,
}

59
src/domain/media/impls.rs Normal file
View File

@ -0,0 +1,59 @@
use sqlx::{Postgres, postgres::{PgValueRef, PgTypeInfo, PgArgumentBuffer}, error::BoxDynError, encode::IsNull};
use super::{Media, MediaList};
impl sqlx::Encode<'_, Postgres> for Media {
fn encode_by_ref(&self, buf: &mut PgArgumentBuffer) -> IsNull {
let binding = serde_json::to_string(self).unwrap();
<&str as sqlx::Encode<Postgres>>::encode(&binding, buf)
}
}
impl sqlx::Decode<'_, Postgres> for Media {
fn decode(value: PgValueRef<'_>) -> Result<Self, BoxDynError> {
let column = value.as_str()?;
match serde_json::from_str(column) {
Ok(listing_state) => Ok(listing_state),
Err(error) => Err(Box::new(error)),
}
}
}
impl sqlx::Type<Postgres> for Media {
fn type_info() -> PgTypeInfo {
PgTypeInfo::with_name("TEXT")
}
fn compatible(ty: &<Postgres as sqlx::Database>::TypeInfo) -> bool {
*ty == Self::type_info()
}
}
impl sqlx::Encode<'_, Postgres> for MediaList {
fn encode_by_ref(&self, buf: &mut PgArgumentBuffer) -> IsNull {
let binding = serde_json::to_string(self).unwrap();
<&str as sqlx::Encode<Postgres>>::encode(&binding, buf)
}
}
impl sqlx::Decode<'_, Postgres> for MediaList {
fn decode(value: PgValueRef<'_>) -> Result<Self, BoxDynError> {
let column = value.as_str()?;
match serde_json::from_str(column) {
Ok(listing_state) => Ok(listing_state),
Err(error) => Err(Box::new(error)),
}
}
}
impl sqlx::Type<Postgres> for MediaList {
fn type_info() -> PgTypeInfo {
PgTypeInfo::with_name("TEXT")
}
fn compatible(ty: &<Postgres as sqlx::Database>::TypeInfo) -> bool {
*ty == Self::type_info()
}
}

16
src/domain/media/mod.rs Normal file
View File

@ -0,0 +1,16 @@
#[cfg(feature = "sqlx")]
pub mod impls;
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub enum Media {
Photo(String),
Video(String),
}
#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct MediaList {
#[serde(rename = "mediaList")]
pub media_list: Vec<Media>,
}

10
src/domain/mod.rs Normal file
View File

@ -0,0 +1,10 @@
pub mod project;
pub mod location;
pub mod agent;
pub mod project_type;
pub mod unit;
pub mod project_state;
pub mod error;
pub mod credential;
pub mod unit_type;
pub mod media;

28
src/domain/project.rs Normal file
View File

@ -0,0 +1,28 @@
use chrono::{DateTime, Utc};
use serde::{Serialize, Deserialize};
use uuid::Uuid;
use super::media::MediaList;
#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct Project {
pub id: Uuid,
#[serde(rename = "agentId")]
pub agent_id: Uuid,
#[serde(rename = "locationId")]
pub location_id: Uuid,
/// Title is optional as the agent can choose not to put the title there (in that case the title will be generated in the frontend)
pub title: Option<String>,
pub description: String,
/// Amount of floors the building/house has
pub floors: i16,
pub media: MediaList,
#[serde(rename = "timeCreated")]
pub time_created: DateTime<Utc>,
#[serde(rename = "lastUpdated")]
pub last_updated: DateTime<Utc>,
}

View File

@ -0,0 +1,31 @@
use sqlx::{Postgres, postgres::{PgValueRef, PgTypeInfo, PgArgumentBuffer}, error::BoxDynError, encode::IsNull};
use super::ProjectState;
use std::str::FromStr;
impl sqlx::Encode<'_, Postgres> for ProjectState {
fn encode_by_ref(&self, buf: &mut PgArgumentBuffer) -> IsNull {
let binding = self.to_string();
<&str as sqlx::Encode<Postgres>>::encode(&binding, buf)
}
}
impl sqlx::Decode<'_, Postgres> for ProjectState {
fn decode(value: PgValueRef<'_>) -> Result<Self, BoxDynError> {
let column = value.as_str()?;
match Self::from_str(column) {
Ok(listing_state) => Ok(listing_state),
Err(error) => Err(Box::new(error)),
}
}
}
impl sqlx::Type<Postgres> for ProjectState {
fn type_info() -> PgTypeInfo {
PgTypeInfo::with_name("VARCHAR")
}
fn compatible(ty: &<Postgres as sqlx::Database>::TypeInfo) -> bool {
*ty == Self::type_info()
}
}

View File

@ -0,0 +1,34 @@
#[cfg(feature = "sqlx")]
pub mod impls;
use std::{fmt::Display, str::FromStr};
use serde::{Deserialize, Serialize};
use super::error::Error;
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum ProjectState {
Finished,
InConstruction,
}
impl Display for ProjectState {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
ProjectState::Finished => write!(f, "Terminado"),
ProjectState::InConstruction => write!(f, "En construcción"),
}
}
}
impl FromStr for ProjectState {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"Terminado" => Ok(Self::Finished),
"En construcción" => Ok(Self::InConstruction),
_ => Err(Error::Parsing),
}
}
}

View File

@ -0,0 +1,32 @@
use sqlx::{Postgres, postgres::{PgValueRef, PgTypeInfo, PgArgumentBuffer}, error::BoxDynError, encode::IsNull};
use super::{ProjectType};
use std::str::FromStr;
impl sqlx::Encode<'_, Postgres> for ProjectType {
fn encode_by_ref(&self, buf: &mut PgArgumentBuffer) -> IsNull {
let binding = self.to_string();
<&str as sqlx::Encode<Postgres>>::encode(&binding, buf)
}
}
impl sqlx::Decode<'_, Postgres> for ProjectType {
fn decode(value: PgValueRef<'_>) -> Result<Self, BoxDynError> {
let column = value.as_str()?;
match Self::from_str(column) {
Ok(listing_state) => Ok(listing_state),
Err(error) => Err(Box::new(error)),
}
}
}
impl sqlx::Type<Postgres> for ProjectType {
fn type_info() -> PgTypeInfo {
PgTypeInfo::with_name("VARCHAR")
}
fn compatible(ty: &<Postgres as sqlx::Database>::TypeInfo) -> bool {
*ty == Self::type_info()
}
}

View File

@ -0,0 +1,45 @@
#[cfg(feature = "sqlx")]
pub mod impls;
use std::{fmt::Display, str::FromStr};
use serde::{Serialize, Deserialize};
use super::error::Error;
#[derive(Serialize, Deserialize, Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord)]
pub enum ProjectType {
#[default]
Apartamento,
Casa,
Oficina,
Local,
Solar,
}
#[allow(unused)]
impl Display for ProjectType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
ProjectType::Apartamento => write!(f, "Apartamento"),
ProjectType::Casa => write!(f, "Casa"),
ProjectType::Oficina => write!(f, "Oficina"),
ProjectType::Local => write!(f, "Local"),
ProjectType::Solar => write!(f, "Solar"),
}
}
}
impl FromStr for ProjectType {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"Apartamento" => Ok(Self::Apartamento),
"Casa" => Ok(Self::Casa),
"Oficina" => Ok(Self::Oficina),
"Local" => Ok(Self::Local),
"Solar" => Ok(Self::Solar),
_ => Err(Error::Parsing),
}
}
}

35
src/domain/unit.rs Normal file
View File

@ -0,0 +1,35 @@
use chrono::{DateTime, Utc};
use serde::{Serialize, Deserialize};
use uuid::Uuid;
use super::{unit_type::UnitType, media::MediaList};
#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq, PartialOrd)]
pub struct Unit {
pub id: Uuid,
#[serde(rename = "projectId")]
pub project_id: Uuid,
/// Let the client convert from usd to whatever currency
#[serde(rename = "priceUsd")]
pub price_usd: f64,
#[serde(rename = "unitType")]
pub unit_type: UnitType,
/// Amount of rooms in unit
pub rooms: i16,
/// Amount of bathrooms in unit
pub bathrooms: i16,
/// In meters squared
pub area: f32,
pub description: String,
pub media: MediaList,
#[serde(rename = "timeCreated")]
pub time_created: DateTime<Utc>,
#[serde(rename = "lastUpdated")]
pub last_updated: DateTime<Utc>,
}

View File

@ -0,0 +1,31 @@
use sqlx::{Postgres, postgres::{PgValueRef, PgTypeInfo, PgArgumentBuffer}, error::BoxDynError, encode::IsNull};
use super::UnitType;
use std::str::FromStr;
impl sqlx::Encode<'_, Postgres> for UnitType {
fn encode_by_ref(&self, buf: &mut PgArgumentBuffer) -> IsNull {
let binding = self.to_string();
<&str as sqlx::Encode<Postgres>>::encode(&binding, buf)
}
}
impl sqlx::Decode<'_, Postgres> for UnitType {
fn decode(value: PgValueRef<'_>) -> Result<Self, BoxDynError> {
let column = value.as_str()?;
match Self::from_str(column) {
Ok(listing_state) => Ok(listing_state),
Err(error) => Err(Box::new(error)),
}
}
}
impl sqlx::Type<Postgres> for UnitType {
fn type_info() -> PgTypeInfo {
PgTypeInfo::with_name("VARCHAR")
}
fn compatible(ty: &<Postgres as sqlx::Database>::TypeInfo) -> bool {
*ty == Self::type_info()
}
}

View File

@ -0,0 +1,36 @@
#[cfg(feature = "sqlx")]
pub mod impls;
use std::{fmt::Display, str::FromStr};
use serde::{Deserialize, Serialize};
use super::error::Error;
#[derive(Serialize, Deserialize, Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum UnitType {
#[default]
ForSale,
NotForSale,
}
impl Display for UnitType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
UnitType::ForSale => write!(f, "Para Venta"),
UnitType::NotForSale => write!(f, "Área Común"),
}
}
}
impl FromStr for UnitType {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"Para Venta" => Ok(Self::ForSale),
"Área Común" => Ok(Self::NotForSale),
_ => Err(Error::Parsing)
}
}
}

0
src/dto/mod.rs Normal file
View File

2
src/lib.rs Normal file
View File

@ -0,0 +1,2 @@
pub mod domain;
pub mod dto;