reinfer_client/resources/
project.rs

1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3use std::str::FromStr;
4
5use crate::{
6    error::{Error, Result},
7    resources::user::Id as UserId,
8};
9
10#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq, Hash)]
11pub struct ProjectName(pub String);
12
13impl FromStr for ProjectName {
14    type Err = Error;
15
16    fn from_str(string: &str) -> Result<Self> {
17        if string
18            .chars()
19            .all(|c| c.is_ascii_alphanumeric() || c == '_' || c == '-')
20        {
21            Ok(Self(string.into()))
22        } else {
23            Err(Error::BadProjectIdentifier {
24                identifier: string.into(),
25            })
26        }
27    }
28}
29
30#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq, Hash)]
31pub struct Id(pub String);
32
33#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
34pub struct Project {
35    // CODE HEALTH: At time of addition, deployed versions of reinfer may not
36    // return project ids.
37    //
38    // This can be removed once reinfer is deployed everywhere.
39    #[serde(default)]
40    pub id: Option<Id>,
41    pub name: ProjectName,
42    pub title: String,
43    pub description: String,
44    pub created_at: DateTime<Utc>,
45    pub updated_at: DateTime<Utc>,
46}
47
48#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
49pub(crate) struct GetProjectResponse {
50    pub project: Project,
51}
52
53#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
54pub(crate) struct GetProjectsResponse {
55    pub projects: Vec<Project>,
56}
57
58#[derive(Debug, Clone, Serialize, PartialEq, Eq, Default)]
59pub struct NewProject<'request> {
60    #[serde(skip_serializing_if = "Option::is_none")]
61    pub title: Option<&'request str>,
62
63    #[serde(skip_serializing_if = "Option::is_none")]
64    pub description: Option<&'request str>,
65}
66
67#[derive(Debug, Clone, Serialize, PartialEq, Eq, Default)]
68pub(crate) struct CreateProjectRequest<'request> {
69    pub project: NewProject<'request>,
70    pub user_ids: &'request [UserId],
71}
72
73#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
74pub(crate) struct CreateProjectResponse {
75    pub project: Project,
76}
77
78#[derive(Debug, Clone, Serialize, PartialEq, Eq, Default)]
79pub struct UpdateProject<'request> {
80    #[serde(skip_serializing_if = "Option::is_none")]
81    pub title: Option<&'request str>,
82
83    #[serde(skip_serializing_if = "Option::is_none")]
84    pub description: Option<&'request str>,
85}
86
87#[derive(Debug, Clone, Serialize, PartialEq, Eq, Default)]
88pub struct UpdateProjectRequest<'request> {
89    pub project: UpdateProject<'request>,
90}
91
92#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
93pub(crate) struct UpdateProjectResponse {
94    pub project: Project,
95}
96
97#[derive(Debug, Clone, Copy, PartialEq, Eq)]
98pub enum ForceDeleteProject {
99    No,
100    Yes,
101}