1use crate::error::{OptimError, Result};
7use chrono::{DateTime, TimeZone, Utc};
8use serde::{Deserialize, Serialize};
9use std::collections::HashMap;
10
11#[derive(Debug, Clone, Serialize, Deserialize)]
13pub struct ConferenceManager {
14 pub conferences: HashMap<String, Conference>,
16 pub submissions: Vec<Submission>,
18 pub alerts: Vec<DeadlineAlert>,
20}
21
22#[derive(Debug, Clone, Serialize, Deserialize)]
24pub struct Conference {
25 pub id: String,
27 pub name: String,
29 pub abbreviation: String,
31 pub description: String,
33 pub url: String,
35 pub ranking: ConferenceRanking,
37 pub research_areas: Vec<String>,
39 pub annual: bool,
41 pub series_info: SeriesInfo,
43 pub dates: ConferenceDates,
45 pub requirements: SubmissionRequirements,
47 pub review_process: ReviewProcess,
49}
50
51#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
53pub enum ConferenceRanking {
54 TopTier,
56 HighQuality,
58 Good,
60 Acceptable,
62 Emerging,
64 Workshop,
66 Unranked,
68}
69
70#[derive(Debug, Clone, Serialize, Deserialize)]
72pub struct SeriesInfo {
73 pub series_number: u32,
75 pub year: u32,
77 pub location: String,
79 pub country: String,
81 pub format: ConferenceFormat,
83}
84
85#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
87pub enum ConferenceFormat {
88 InPerson,
90 Virtual,
92 Hybrid,
94}
95
96#[derive(Debug, Clone, Serialize, Deserialize)]
98pub struct ConferenceDates {
99 pub abstract_deadline: Option<DateTime<Utc>>,
101 pub paper_deadline: DateTime<Utc>,
103 pub notification_date: DateTime<Utc>,
105 pub camera_ready_deadline: DateTime<Utc>,
107 pub conference_start: DateTime<Utc>,
109 pub conference_end: DateTime<Utc>,
111}
112
113#[derive(Debug, Clone, Serialize, Deserialize)]
115pub struct SubmissionRequirements {
116 pub page_limit: u32,
118 pub word_limit: Option<u32>,
120 pub format: FormatRequirements,
122 pub required_sections: Vec<String>,
124 pub supplementary_allowed: bool,
126 pub anonymous_submission: bool,
128 pub double_blind: bool,
130}
131
132#[derive(Debug, Clone, Serialize, Deserialize)]
134pub struct FormatRequirements {
135 pub template: String,
137 pub font_size: u32,
139 pub line_spacing: f64,
141 pub margins: String,
143 pub citation_style: String,
145 pub file_format: Vec<String>,
147}
148
149#[derive(Debug, Clone, Serialize, Deserialize)]
151pub struct ReviewProcess {
152 pub reviewers_per_paper: u32,
154 pub review_criteria: Vec<String>,
156 pub rebuttal_allowed: bool,
158 pub acceptance_rate: Option<f64>,
160 pub review_format: ReviewFormat,
162}
163
164#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
166pub enum ReviewFormat {
167 NumericalScores,
169 WrittenOnly,
171 Mixed,
173}
174
175#[derive(Debug, Clone, Serialize, Deserialize)]
177pub struct Submission {
178 pub id: String,
180 pub conference_id: String,
182 pub paper_id: String,
184 pub status: SubmissionStatus,
186 pub submitted_at: DateTime<Utc>,
188 pub track: Option<String>,
190 pub materials: SubmissionMaterials,
192 pub reviews: Vec<Review>,
194 pub decision: Option<Decision>,
196}
197
198#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
200pub enum SubmissionStatus {
201 Draft,
203 Submitted,
205 UnderReview,
207 Rebuttal,
209 Decided,
211 CameraReady,
213 Withdrawn,
215}
216
217#[derive(Debug, Clone, Serialize, Deserialize)]
219pub struct SubmissionMaterials {
220 pub paper_file: String,
222 pub supplementary_files: Vec<String>,
224 pub abstracttext: String,
226 pub keywords: Vec<String>,
228 pub authors: Option<Vec<String>>,
230}
231
232#[derive(Debug, Clone, Serialize, Deserialize)]
234pub struct Review {
235 pub id: String,
237 pub reviewer: String,
239 pub overall_score: Option<f64>,
241 pub detailed_scores: HashMap<String, f64>,
243 pub reviewtext: String,
245 pub recommendation: ReviewRecommendation,
247 pub reviewed_at: DateTime<Utc>,
249}
250
251#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
253pub enum ReviewRecommendation {
254 StrongAccept,
256 Accept,
258 WeakAccept,
260 Borderline,
262 WeakReject,
264 Reject,
266 StrongReject,
268}
269
270#[derive(Debug, Clone, Serialize, Deserialize)]
272pub struct Decision {
273 pub outcome: DecisionOutcome,
275 pub decided_at: DateTime<Utc>,
277 pub editor_comments: Option<String>,
279 pub required_revisions: Vec<String>,
281}
282
283#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
285pub enum DecisionOutcome {
286 Accept,
288 AcceptMinorRevisions,
290 AcceptMajorRevisions,
292 ConditionalAccept,
294 Reject,
296 RejectAndResubmit,
298}
299
300#[derive(Debug, Clone, Serialize, Deserialize)]
302pub struct DeadlineAlert {
303 pub id: String,
305 pub conference_id: String,
307 pub deadline_type: DeadlineType,
309 pub alert_date: DateTime<Utc>,
311 pub days_before: u32,
313 pub message: String,
315 pub sent: bool,
317}
318
319#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
321pub enum DeadlineType {
322 AbstractSubmission,
324 PaperSubmission,
326 Notification,
328 CameraReady,
330 ConferenceStart,
332}
333
334impl Default for ConferenceManager {
335 fn default() -> Self {
336 Self::new()
337 }
338}
339
340impl ConferenceManager {
341 pub fn new() -> Self {
343 Self {
344 conferences: HashMap::new(),
345 submissions: Vec::new(),
346 alerts: Vec::new(),
347 }
348 }
349
350 pub fn add_conference(&mut self, conference: Conference) {
352 self.conferences.insert(conference.id.clone(), conference);
353 }
354
355 pub fn submit_paper(
357 &mut self,
358 conference_id: &str,
359 paper_id: &str,
360 materials: SubmissionMaterials,
361 ) -> Result<String> {
362 if !self.conferences.contains_key(conference_id) {
363 return Err(OptimError::InvalidConfig(format!(
364 "Conference '{}' not found",
365 conference_id
366 )));
367 }
368
369 let submission_id = uuid::Uuid::new_v4().to_string();
370 let submission = Submission {
371 id: submission_id.clone(),
372 conference_id: conference_id.to_string(),
373 paper_id: paper_id.to_string(),
374 status: SubmissionStatus::Submitted,
375 submitted_at: Utc::now(),
376 track: None,
377 materials,
378 reviews: Vec::new(),
379 decision: None,
380 };
381
382 self.submissions.push(submission);
383 Ok(submission_id)
384 }
385
386 pub fn get_upcoming_deadlines(
388 &self,
389 days_ahead: u32,
390 ) -> Vec<(&Conference, DeadlineType, DateTime<Utc>)> {
391 let mut deadlines = Vec::new();
392 let now = Utc::now();
393 let future_limit = now + chrono::Duration::days(days_ahead as i64);
394
395 for conference in self.conferences.values() {
396 let dates = &conference.dates;
397
398 if let Some(abstract_deadline) = dates.abstract_deadline {
399 if abstract_deadline > now && abstract_deadline <= future_limit {
400 deadlines.push((
401 conference,
402 DeadlineType::AbstractSubmission,
403 abstract_deadline,
404 ));
405 }
406 }
407
408 if dates.paper_deadline > now && dates.paper_deadline <= future_limit {
409 deadlines.push((
410 conference,
411 DeadlineType::PaperSubmission,
412 dates.paper_deadline,
413 ));
414 }
415
416 if dates.notification_date > now && dates.notification_date <= future_limit {
417 deadlines.push((
418 conference,
419 DeadlineType::Notification,
420 dates.notification_date,
421 ));
422 }
423
424 if dates.camera_ready_deadline > now && dates.camera_ready_deadline <= future_limit {
425 deadlines.push((
426 conference,
427 DeadlineType::CameraReady,
428 dates.camera_ready_deadline,
429 ));
430 }
431
432 if dates.conference_start > now && dates.conference_start <= future_limit {
433 deadlines.push((
434 conference,
435 DeadlineType::ConferenceStart,
436 dates.conference_start,
437 ));
438 }
439 }
440
441 deadlines.sort_by_key(|a| a.2);
443 deadlines
444 }
445
446 pub fn search_conferences(&self, research_area: &str) -> Vec<&Conference> {
448 self.conferences
449 .values()
450 .filter(|conf| {
451 conf.research_areas
452 .iter()
453 .any(|area| area.to_lowercase().contains(&research_area.to_lowercase()))
454 })
455 .collect()
456 }
457
458 pub fn get_conferences_by_ranking(&self, ranking: ConferenceRanking) -> Vec<&Conference> {
460 self.conferences
461 .values()
462 .filter(|conf| conf.ranking == ranking)
463 .collect()
464 }
465
466 pub fn load_standard_conferences(&mut self) {
468 self.add_conference(Self::create_neurips_conference());
470 self.add_conference(Self::create_icml_conference());
471 self.add_conference(Self::create_iclr_conference());
472 self.add_conference(Self::create_aaai_conference());
473 self.add_conference(Self::create_ijcai_conference());
474 }
475
476 fn create_neurips_conference() -> Conference {
477 Conference {
478 id: "neurips2024".to_string(),
479 name: "Conference on Neural Information Processing Systems".to_string(),
480 abbreviation: "NeurIPS".to_string(),
481 description: "Premier conference on neural information processing systems".to_string(),
482 url: "https://neurips.cc/".to_string(),
483 ranking: ConferenceRanking::TopTier,
484 research_areas: vec![
485 "Machine Learning".to_string(),
486 "Deep Learning".to_string(),
487 "Neural Networks".to_string(),
488 "Optimization".to_string(),
489 ],
490 annual: true,
491 series_info: SeriesInfo {
492 series_number: 38,
493 year: 2024,
494 location: "Vancouver".to_string(),
495 country: "Canada".to_string(),
496 format: ConferenceFormat::Hybrid,
497 },
498 dates: ConferenceDates {
499 abstract_deadline: Some(
500 chrono::Utc
501 .with_ymd_and_hms(2024, 5, 15, 23, 59, 59)
502 .single()
503 .expect("invalid datetime"),
504 ),
505 paper_deadline: chrono::Utc
506 .with_ymd_and_hms(2024, 5, 22, 23, 59, 59)
507 .single()
508 .expect("invalid datetime"),
509 notification_date: chrono::Utc
510 .with_ymd_and_hms(2024, 9, 25, 12, 0, 0)
511 .single()
512 .expect("invalid datetime"),
513 camera_ready_deadline: chrono::Utc
514 .with_ymd_and_hms(2024, 10, 30, 23, 59, 59)
515 .single()
516 .expect("invalid datetime"),
517 conference_start: chrono::Utc
518 .with_ymd_and_hms(2024, 12, 10, 9, 0, 0)
519 .single()
520 .expect("invalid datetime"),
521 conference_end: chrono::Utc
522 .with_ymd_and_hms(2024, 12, 16, 18, 0, 0)
523 .single()
524 .expect("invalid datetime"),
525 },
526 requirements: SubmissionRequirements {
527 page_limit: 9,
528 word_limit: None,
529 format: FormatRequirements {
530 template: "NeurIPS 2024 LaTeX template".to_string(),
531 font_size: 10,
532 line_spacing: 1.0,
533 margins: "1 inch".to_string(),
534 citation_style: "NeurIPS".to_string(),
535 file_format: vec!["PDF".to_string()],
536 },
537 required_sections: vec![
538 "Abstract".to_string(),
539 "Introduction".to_string(),
540 "Related Work".to_string(),
541 "Method".to_string(),
542 "Experiments".to_string(),
543 "Conclusion".to_string(),
544 ],
545 supplementary_allowed: true,
546 anonymous_submission: true,
547 double_blind: true,
548 },
549 review_process: ReviewProcess {
550 reviewers_per_paper: 3,
551 review_criteria: vec![
552 "Technical Quality".to_string(),
553 "Novelty".to_string(),
554 "Significance".to_string(),
555 "Clarity".to_string(),
556 ],
557 rebuttal_allowed: true,
558 acceptance_rate: Some(0.26), review_format: ReviewFormat::Mixed,
560 },
561 }
562 }
563
564 fn create_icml_conference() -> Conference {
565 Conference {
566 id: "icml2024".to_string(),
567 name: "International Conference on Machine Learning".to_string(),
568 abbreviation: "ICML".to_string(),
569 description: "Premier international conference on machine learning".to_string(),
570 url: "https://icml.cc/".to_string(),
571 ranking: ConferenceRanking::TopTier,
572 research_areas: vec![
573 "Machine Learning".to_string(),
574 "Optimization".to_string(),
575 "Statistical Learning".to_string(),
576 "Deep Learning".to_string(),
577 ],
578 annual: true,
579 series_info: SeriesInfo {
580 series_number: 41,
581 year: 2024,
582 location: "Vienna".to_string(),
583 country: "Austria".to_string(),
584 format: ConferenceFormat::Hybrid,
585 },
586 dates: ConferenceDates {
587 abstract_deadline: None,
588 paper_deadline: chrono::Utc
589 .with_ymd_and_hms(2024, 2, 1, 23, 59, 59)
590 .single()
591 .expect("invalid datetime"),
592 notification_date: chrono::Utc
593 .with_ymd_and_hms(2024, 5, 1, 12, 0, 0)
594 .single()
595 .expect("invalid datetime"),
596 camera_ready_deadline: chrono::Utc
597 .with_ymd_and_hms(2024, 6, 1, 23, 59, 59)
598 .single()
599 .expect("invalid datetime"),
600 conference_start: chrono::Utc
601 .with_ymd_and_hms(2024, 7, 21, 9, 0, 0)
602 .single()
603 .expect("invalid datetime"),
604 conference_end: chrono::Utc
605 .with_ymd_and_hms(2024, 7, 27, 18, 0, 0)
606 .single()
607 .expect("invalid datetime"),
608 },
609 requirements: SubmissionRequirements {
610 page_limit: 8,
611 word_limit: None,
612 format: FormatRequirements {
613 template: "ICML 2024 LaTeX template".to_string(),
614 font_size: 10,
615 line_spacing: 1.0,
616 margins: "1 inch".to_string(),
617 citation_style: "ICML".to_string(),
618 file_format: vec!["PDF".to_string()],
619 },
620 required_sections: vec![
621 "Abstract".to_string(),
622 "Introduction".to_string(),
623 "Methods".to_string(),
624 "Results".to_string(),
625 "Conclusion".to_string(),
626 ],
627 supplementary_allowed: true,
628 anonymous_submission: true,
629 double_blind: true,
630 },
631 review_process: ReviewProcess {
632 reviewers_per_paper: 3,
633 review_criteria: vec![
634 "Technical Quality".to_string(),
635 "Clarity".to_string(),
636 "Originality".to_string(),
637 "Significance".to_string(),
638 ],
639 rebuttal_allowed: true,
640 acceptance_rate: Some(0.23), review_format: ReviewFormat::Mixed,
642 },
643 }
644 }
645
646 fn create_iclr_conference() -> Conference {
647 Conference {
648 id: "iclr2024".to_string(),
649 name: "International Conference on Learning Representations".to_string(),
650 abbreviation: "ICLR".to_string(),
651 description: "Conference focused on learning representations".to_string(),
652 url: "https://iclr.cc/".to_string(),
653 ranking: ConferenceRanking::TopTier,
654 research_areas: vec![
655 "Deep Learning".to_string(),
656 "Representation Learning".to_string(),
657 "Neural Networks".to_string(),
658 "Optimization".to_string(),
659 ],
660 annual: true,
661 series_info: SeriesInfo {
662 series_number: 12,
663 year: 2024,
664 location: "Vienna".to_string(),
665 country: "Austria".to_string(),
666 format: ConferenceFormat::Hybrid,
667 },
668 dates: ConferenceDates {
669 abstract_deadline: Some(
670 chrono::Utc
671 .with_ymd_and_hms(2023, 9, 28, 23, 59, 59)
672 .single()
673 .expect("invalid datetime"),
674 ),
675 paper_deadline: chrono::Utc
676 .with_ymd_and_hms(2023, 10, 2, 23, 59, 59)
677 .single()
678 .expect("invalid datetime"),
679 notification_date: chrono::Utc
680 .with_ymd_and_hms(2024, 1, 15, 12, 0, 0)
681 .single()
682 .expect("invalid datetime"),
683 camera_ready_deadline: chrono::Utc
684 .with_ymd_and_hms(2024, 2, 29, 23, 59, 59)
685 .single()
686 .expect("invalid datetime"),
687 conference_start: chrono::Utc
688 .with_ymd_and_hms(2024, 5, 7, 9, 0, 0)
689 .single()
690 .expect("invalid datetime"),
691 conference_end: chrono::Utc
692 .with_ymd_and_hms(2024, 5, 11, 18, 0, 0)
693 .single()
694 .expect("invalid datetime"),
695 },
696 requirements: SubmissionRequirements {
697 page_limit: 9,
698 word_limit: None,
699 format: FormatRequirements {
700 template: "ICLR 2024 LaTeX template".to_string(),
701 font_size: 10,
702 line_spacing: 1.0,
703 margins: "1 inch".to_string(),
704 citation_style: "ICLR".to_string(),
705 file_format: vec!["PDF".to_string()],
706 },
707 required_sections: vec![
708 "Abstract".to_string(),
709 "Introduction".to_string(),
710 "Related Work".to_string(),
711 "Method".to_string(),
712 "Experiments".to_string(),
713 "Conclusion".to_string(),
714 ],
715 supplementary_allowed: true,
716 anonymous_submission: true,
717 double_blind: true,
718 },
719 review_process: ReviewProcess {
720 reviewers_per_paper: 3,
721 review_criteria: vec![
722 "Technical Quality".to_string(),
723 "Clarity".to_string(),
724 "Originality".to_string(),
725 "Significance".to_string(),
726 ],
727 rebuttal_allowed: true,
728 acceptance_rate: Some(0.31), review_format: ReviewFormat::Mixed,
730 },
731 }
732 }
733
734 fn create_aaai_conference() -> Conference {
735 Conference {
736 id: "aaai2024".to_string(),
737 name: "AAAI Conference on Artificial Intelligence".to_string(),
738 abbreviation: "AAAI".to_string(),
739 description: "Conference on artificial intelligence".to_string(),
740 url: "https://aaai.org/".to_string(),
741 ranking: ConferenceRanking::TopTier,
742 research_areas: vec![
743 "Artificial Intelligence".to_string(),
744 "Machine Learning".to_string(),
745 "Knowledge Representation".to_string(),
746 "Planning".to_string(),
747 ],
748 annual: true,
749 series_info: SeriesInfo {
750 series_number: 38,
751 year: 2024,
752 location: "Vancouver".to_string(),
753 country: "Canada".to_string(),
754 format: ConferenceFormat::Hybrid,
755 },
756 dates: ConferenceDates {
757 abstract_deadline: Some(
758 chrono::Utc
759 .with_ymd_and_hms(2023, 8, 15, 23, 59, 59)
760 .single()
761 .expect("invalid datetime"),
762 ),
763 paper_deadline: chrono::Utc
764 .with_ymd_and_hms(2023, 8, 19, 23, 59, 59)
765 .single()
766 .expect("invalid datetime"),
767 notification_date: chrono::Utc
768 .with_ymd_and_hms(2023, 12, 9, 12, 0, 0)
769 .single()
770 .expect("invalid datetime"),
771 camera_ready_deadline: chrono::Utc
772 .with_ymd_and_hms(2024, 1, 15, 23, 59, 59)
773 .single()
774 .expect("invalid datetime"),
775 conference_start: chrono::Utc
776 .with_ymd_and_hms(2024, 2, 20, 9, 0, 0)
777 .single()
778 .expect("invalid datetime"),
779 conference_end: chrono::Utc
780 .with_ymd_and_hms(2024, 2, 27, 18, 0, 0)
781 .single()
782 .expect("invalid datetime"),
783 },
784 requirements: SubmissionRequirements {
785 page_limit: 7,
786 word_limit: None,
787 format: FormatRequirements {
788 template: "AAAI 2024 LaTeX template".to_string(),
789 font_size: 10,
790 line_spacing: 1.0,
791 margins: "0.75 inch".to_string(),
792 citation_style: "AAAI".to_string(),
793 file_format: vec!["PDF".to_string()],
794 },
795 required_sections: vec![
796 "Abstract".to_string(),
797 "Introduction".to_string(),
798 "Related Work".to_string(),
799 "Approach".to_string(),
800 "Experiments".to_string(),
801 "Conclusion".to_string(),
802 ],
803 supplementary_allowed: false,
804 anonymous_submission: true,
805 double_blind: true,
806 },
807 review_process: ReviewProcess {
808 reviewers_per_paper: 3,
809 review_criteria: vec![
810 "Technical Quality".to_string(),
811 "Novelty".to_string(),
812 "Significance".to_string(),
813 "Clarity".to_string(),
814 ],
815 rebuttal_allowed: false,
816 acceptance_rate: Some(0.23), review_format: ReviewFormat::NumericalScores,
818 },
819 }
820 }
821
822 fn create_ijcai_conference() -> Conference {
823 Conference {
824 id: "ijcai2024".to_string(),
825 name: "International Joint Conference on Artificial Intelligence".to_string(),
826 abbreviation: "IJCAI".to_string(),
827 description: "International conference on artificial intelligence".to_string(),
828 url: "https://ijcai.org/".to_string(),
829 ranking: ConferenceRanking::TopTier,
830 research_areas: vec![
831 "Artificial Intelligence".to_string(),
832 "Machine Learning".to_string(),
833 "Automated Reasoning".to_string(),
834 "Multi-agent Systems".to_string(),
835 ],
836 annual: true,
837 series_info: SeriesInfo {
838 series_number: 33,
839 year: 2024,
840 location: "Jeju".to_string(),
841 country: "South Korea".to_string(),
842 format: ConferenceFormat::Hybrid,
843 },
844 dates: ConferenceDates {
845 abstract_deadline: Some(
846 chrono::Utc
847 .with_ymd_and_hms(2024, 1, 17, 23, 59, 59)
848 .single()
849 .expect("invalid datetime"),
850 ),
851 paper_deadline: chrono::Utc
852 .with_ymd_and_hms(2024, 1, 24, 23, 59, 59)
853 .single()
854 .expect("invalid datetime"),
855 notification_date: chrono::Utc
856 .with_ymd_and_hms(2024, 4, 16, 12, 0, 0)
857 .single()
858 .expect("invalid datetime"),
859 camera_ready_deadline: chrono::Utc
860 .with_ymd_and_hms(2024, 5, 15, 23, 59, 59)
861 .single()
862 .expect("invalid datetime"),
863 conference_start: chrono::Utc
864 .with_ymd_and_hms(2024, 8, 3, 9, 0, 0)
865 .single()
866 .expect("invalid datetime"),
867 conference_end: chrono::Utc
868 .with_ymd_and_hms(2024, 8, 9, 18, 0, 0)
869 .single()
870 .expect("invalid datetime"),
871 },
872 requirements: SubmissionRequirements {
873 page_limit: 7,
874 word_limit: None,
875 format: FormatRequirements {
876 template: "IJCAI 2024 LaTeX template".to_string(),
877 font_size: 10,
878 line_spacing: 1.0,
879 margins: "0.75 inch".to_string(),
880 citation_style: "IJCAI".to_string(),
881 file_format: vec!["PDF".to_string()],
882 },
883 required_sections: vec![
884 "Abstract".to_string(),
885 "Introduction".to_string(),
886 "Background".to_string(),
887 "Approach".to_string(),
888 "Experiments".to_string(),
889 "Conclusion".to_string(),
890 ],
891 supplementary_allowed: false,
892 anonymous_submission: true,
893 double_blind: true,
894 },
895 review_process: ReviewProcess {
896 reviewers_per_paper: 3,
897 review_criteria: vec![
898 "Technical Quality".to_string(),
899 "Novelty".to_string(),
900 "Significance".to_string(),
901 "Clarity".to_string(),
902 ],
903 rebuttal_allowed: true,
904 acceptance_rate: Some(0.15), review_format: ReviewFormat::Mixed,
906 },
907 }
908 }
909}
910
911#[cfg(test)]
912mod tests {
913 use super::*;
914
915 #[test]
916 fn test_conference_manager_creation() {
917 let manager = ConferenceManager::new();
918 assert!(manager.conferences.is_empty());
919 assert!(manager.submissions.is_empty());
920 }
921
922 #[test]
923 fn test_load_standard_conferences() {
924 let mut manager = ConferenceManager::new();
925 manager.load_standard_conferences();
926
927 assert!(manager.conferences.contains_key("neurips2024"));
928 assert!(manager.conferences.contains_key("icml2024"));
929 assert!(manager.conferences.contains_key("iclr2024"));
930 assert!(manager.conferences.contains_key("aaai2024"));
931 assert!(manager.conferences.contains_key("ijcai2024"));
932 }
933
934 #[test]
935 fn test_search_conferences() {
936 let mut manager = ConferenceManager::new();
937 manager.load_standard_conferences();
938
939 let ml_conferences = manager.search_conferences("Machine Learning");
940 assert!(!ml_conferences.is_empty());
941
942 let top_tier = manager.get_conferences_by_ranking(ConferenceRanking::TopTier);
943 assert!(!top_tier.is_empty());
944 }
945}