use crate::ticket_tally::TicketTally;
use super::*;
#[cfg(any(feature = "query_message", feature = "ticket"))]
#[derive(
Deserialize_repr,
Serialize_repr,
Debug,
Clone,
Copy,
Default,
Hash,
PartialEq,
Eq,
PartialOrd,
Ord,
strum::AsRefStr,
strum::EnumIter,
)]
#[repr(u32)]
pub enum MsgTopic {
#[default]
#[strum(serialize = "Chat")]
CustomMessage = 2_u32.pow(0),
#[strum(serialize = "Brief Updated")]
BriefUpdated = 2_u32.pow(1),
#[strum(serialize = "Staff Assigned")]
StaffAssigned = 2_u32.pow(2),
#[strum(serialize = "WIP|Daily")]
WipSnapshot = 2_u32.pow(3),
#[strum(serialize = "Feedback Addressed")]
FeedbackSnapshot = 2_u32.pow(4),
#[strum(serialize = "Asset Uploaded")]
AssetUploaded = 2_u32.pow(5),
#[strum(serialize = "Asset Replaced")]
AssetReplaced = 2_u32.pow(6),
#[strum(serialize = "AD Feedback")]
AdFeedback = 2_u32.pow(7),
#[strum(serialize = "AD Approval")]
AdApproval = 2_u32.pow(8),
#[strum(serialize = "Client Feedback")]
ClientFeedback = 2_u32.pow(9),
#[strum(serialize = "Client Approval")]
ClientApproval = 2_u32.pow(10),
#[strum(serialize = "Submit for Review")]
SubmitForReview = 2_u32.pow(11),
#[strum(serialize = "QC Run")]
QcRun = 2_u32.pow(12),
#[strum(serialize = "P4 Bridge")]
P4Bridge = 2_u32.pow(13),
#[strum(serialize = "Outgoing Delivery")]
OutgoingDelivery = 2_u32.pow(15),
#[strum(serialize = "Internal Publish")]
InternalPublish = 2_u32.pow(16),
#[strum(serialize = "Asset Splitted by Previz")]
AssetSplittedByPreviz = 2_u32.pow(17),
#[strum(serialize = "SubTicket Closed")]
AddressingAccepted = 2_u32.pow(18),
Defect = 2_u32.pow(19),
}
#[cfg(any(feature = "query_message", feature = "ticket"))]
impl MsgTopic {
pub fn is_handwritten(&self) -> bool {
matches!(&self, Self::CustomMessage)
}
pub fn allow_subscription(&self) -> bool {
match self {
Self::CustomMessage | Self::Defect
=> false,
_ => true,
}
}
pub fn system() -> BTreeSet<Self> {
Self::iter().filter(|t| t.allow_subscription()).collect()
}
pub fn handwritten() -> BTreeSet<Self> {
BTreeSet::from([Self::CustomMessage])
}
pub fn all() -> BTreeSet<Self> {
Self::iter().collect()
}
pub fn as_vec_u32(topics: &BTreeSet<Self>) -> Vec<u32> {
topics.iter().map(|t| *t as u32).collect()
}
pub fn into_vec_u32(topics: BTreeSet<Self>) -> Vec<u32> {
topics.into_iter().map(|t| t as u32).collect()
}
pub fn subject(&self, asset: &AssetExcerpt) -> String {
if let Self::AddressingAccepted = &self {
format!("GREAT JOB! {}", asset.name)
} else {
format!("{}: {}", self.as_ref().to_uppercase(), asset.name)
}
}
pub fn receipt_content(
&self,
assignees: &[Staff],
working_step: Option<&AssetStatus>,
phase: Option<&VcsLiteSession>,
ticket_tally: Option<&TicketTally>,
) -> AnyResult<String> {
let empty_content = || Ok(String::new());
let content = match self {
Self::BriefUpdated | Self::WipSnapshot | Self::FeedbackSnapshot => empty_content(),
Self::StaffAssigned => Ok(crate::user::make_assignee_str(assignees.iter())),
Self::AdFeedback | Self::ClientFeedback => Ok(if let Some(tally) = ticket_tally {
tally.genesis_headline()
} else {
"Please check".to_owned()
}),
Self::AddressingAccepted => Ok(if let Some(tally) = ticket_tally {
tally.progress_headline()
} else {
"Please continue addressing the rest of the Subtickets".to_owned()
}),
Self::AdApproval | Self::ClientApproval => Ok("Thanks and Congratz".to_string()),
Self::SubmitForReview => Ok("Feedback is AD Approved".to_string()),
Self::AssetUploaded | Self::AssetReplaced => Ok(format!(
"Phase: {}",
phase.context("No working phase")?.as_ref()
)),
Self::AssetSplittedByPreviz
| Self::QcRun
| Self::P4Bridge
| Self::OutgoingDelivery
| Self::InternalPublish => Err(anyhow!(
"Receipt content is unimplemented for {}",
self.as_ref()
)),
Self::CustomMessage | Self::Defect => {
Err(anyhow!("Unexpected request of receipt content"))
}
};
if content.is_ok() {
if let Some(step) = working_step {
Ok(format!(
"{}; {}",
step.as_ref().to_uppercase(),
content.unwrap()
))
} else {
Ok(format!("No Step 😨; {}", content.unwrap()))
}
} else {
content
}
}
pub fn receipt_recipients(
&self,
assignees: &[Staff],
roles: &RoleMap,
) -> AnyResult<HashSet<Staff>> {
let a = || assignees.iter().map(|s| s.clone()).collect();
match self {
Self::AdFeedback
| Self::AdApproval
| Self::BriefUpdated
| Self::StaffAssigned
| Self::WipSnapshot
| Self::FeedbackSnapshot
| Self::ClientFeedback
| Self::ClientApproval
| Self::Defect => Ok(roles.assignees_and_supervisors(&a(), true, false)),
Self::AddressingAccepted => Ok(roles.assignees_and_supervisors(&a(), false, false)),
Self::SubmitForReview => Ok(roles.assignees_and_team_leads(&a())),
Self::AssetUploaded | Self::AssetReplaced | Self::AssetSplittedByPreviz => {
Ok(roles.supervisors(true))
}
Self::OutgoingDelivery => Ok(roles.supervisors_and_watchers(true)),
Self::InternalPublish => Ok(roles.supervisors(false)),
Self::QcRun | Self::P4Bridge => Err(anyhow!(
"Receipt recipients is unimplemented for {}",
self.as_ref()
)),
Self::CustomMessage => Err(anyhow!("Unexpected request of receipt recipients")),
}
}
}
#[cfg(all(any(feature = "query_message", feature = "ticket"), feature = "gui"))]
pub fn msg_topic_options_ui(topic: &mut MsgTopic, ui: &mut egui::Ui) {
egui::ComboBox::from_label("Topic")
.selected_text(topic.as_ref())
.show_ui(ui, |ui| {
for t in MsgTopic::iter() {
ui.selectable_value(topic, t, t.as_ref());
}
});
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
#[cfg(any(feature = "query_message", feature = "ticket"))]
fn system_qms_topics() {
let s = MsgTopic::system();
eprintln!("System message topics: {:?}", s);
eprintln!("Topics as Vec<u32>: {:?}", MsgTopic::into_vec_u32(s));
}
}