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(|a, b| a.2.cmp(&b.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 .unwrap(),
503 ),
504 paper_deadline: chrono::Utc
505 .with_ymd_and_hms(2024, 5, 22, 23, 59, 59)
506 .unwrap(),
507 notification_date: chrono::Utc.with_ymd_and_hms(2024, 9, 25, 12, 0, 0).unwrap(),
508 camera_ready_deadline: chrono::Utc
509 .with_ymd_and_hms(2024, 10, 30, 23, 59, 59)
510 .unwrap(),
511 conference_start: chrono::Utc.with_ymd_and_hms(2024, 12, 10, 9, 0, 0).unwrap(),
512 conference_end: chrono::Utc
513 .with_ymd_and_hms(2024, 12, 16, 18, 0, 0)
514 .unwrap(),
515 },
516 requirements: SubmissionRequirements {
517 page_limit: 9,
518 word_limit: None,
519 format: FormatRequirements {
520 template: "NeurIPS 2024 LaTeX template".to_string(),
521 font_size: 10,
522 line_spacing: 1.0,
523 margins: "1 inch".to_string(),
524 citation_style: "NeurIPS".to_string(),
525 file_format: vec!["PDF".to_string()],
526 },
527 required_sections: vec![
528 "Abstract".to_string(),
529 "Introduction".to_string(),
530 "Related Work".to_string(),
531 "Method".to_string(),
532 "Experiments".to_string(),
533 "Conclusion".to_string(),
534 ],
535 supplementary_allowed: true,
536 anonymous_submission: true,
537 double_blind: true,
538 },
539 review_process: ReviewProcess {
540 reviewers_per_paper: 3,
541 review_criteria: vec![
542 "Technical Quality".to_string(),
543 "Novelty".to_string(),
544 "Significance".to_string(),
545 "Clarity".to_string(),
546 ],
547 rebuttal_allowed: true,
548 acceptance_rate: Some(0.26), review_format: ReviewFormat::Mixed,
550 },
551 }
552 }
553
554 fn create_icml_conference() -> Conference {
555 Conference {
556 id: "icml2024".to_string(),
557 name: "International Conference on Machine Learning".to_string(),
558 abbreviation: "ICML".to_string(),
559 description: "Premier international conference on machine learning".to_string(),
560 url: "https://icml.cc/".to_string(),
561 ranking: ConferenceRanking::TopTier,
562 research_areas: vec![
563 "Machine Learning".to_string(),
564 "Optimization".to_string(),
565 "Statistical Learning".to_string(),
566 "Deep Learning".to_string(),
567 ],
568 annual: true,
569 series_info: SeriesInfo {
570 series_number: 41,
571 year: 2024,
572 location: "Vienna".to_string(),
573 country: "Austria".to_string(),
574 format: ConferenceFormat::Hybrid,
575 },
576 dates: ConferenceDates {
577 abstract_deadline: None,
578 paper_deadline: chrono::Utc
579 .with_ymd_and_hms(2024, 2, 1, 23, 59, 59)
580 .unwrap(),
581 notification_date: chrono::Utc.with_ymd_and_hms(2024, 5, 1, 12, 0, 0).unwrap(),
582 camera_ready_deadline: chrono::Utc
583 .with_ymd_and_hms(2024, 6, 1, 23, 59, 59)
584 .unwrap(),
585 conference_start: chrono::Utc.with_ymd_and_hms(2024, 7, 21, 9, 0, 0).unwrap(),
586 conference_end: chrono::Utc.with_ymd_and_hms(2024, 7, 27, 18, 0, 0).unwrap(),
587 },
588 requirements: SubmissionRequirements {
589 page_limit: 8,
590 word_limit: None,
591 format: FormatRequirements {
592 template: "ICML 2024 LaTeX template".to_string(),
593 font_size: 10,
594 line_spacing: 1.0,
595 margins: "1 inch".to_string(),
596 citation_style: "ICML".to_string(),
597 file_format: vec!["PDF".to_string()],
598 },
599 required_sections: vec![
600 "Abstract".to_string(),
601 "Introduction".to_string(),
602 "Methods".to_string(),
603 "Results".to_string(),
604 "Conclusion".to_string(),
605 ],
606 supplementary_allowed: true,
607 anonymous_submission: true,
608 double_blind: true,
609 },
610 review_process: ReviewProcess {
611 reviewers_per_paper: 3,
612 review_criteria: vec![
613 "Technical Quality".to_string(),
614 "Clarity".to_string(),
615 "Originality".to_string(),
616 "Significance".to_string(),
617 ],
618 rebuttal_allowed: true,
619 acceptance_rate: Some(0.23), review_format: ReviewFormat::Mixed,
621 },
622 }
623 }
624
625 fn create_iclr_conference() -> Conference {
626 Conference {
627 id: "iclr2024".to_string(),
628 name: "International Conference on Learning Representations".to_string(),
629 abbreviation: "ICLR".to_string(),
630 description: "Conference focused on learning representations".to_string(),
631 url: "https://iclr.cc/".to_string(),
632 ranking: ConferenceRanking::TopTier,
633 research_areas: vec![
634 "Deep Learning".to_string(),
635 "Representation Learning".to_string(),
636 "Neural Networks".to_string(),
637 "Optimization".to_string(),
638 ],
639 annual: true,
640 series_info: SeriesInfo {
641 series_number: 12,
642 year: 2024,
643 location: "Vienna".to_string(),
644 country: "Austria".to_string(),
645 format: ConferenceFormat::Hybrid,
646 },
647 dates: ConferenceDates {
648 abstract_deadline: Some(
649 chrono::Utc
650 .with_ymd_and_hms(2023, 9, 28, 23, 59, 59)
651 .unwrap(),
652 ),
653 paper_deadline: chrono::Utc
654 .with_ymd_and_hms(2023, 10, 2, 23, 59, 59)
655 .unwrap(),
656 notification_date: chrono::Utc.with_ymd_and_hms(2024, 1, 15, 12, 0, 0).unwrap(),
657 camera_ready_deadline: chrono::Utc
658 .with_ymd_and_hms(2024, 2, 29, 23, 59, 59)
659 .unwrap(),
660 conference_start: chrono::Utc.with_ymd_and_hms(2024, 5, 7, 9, 0, 0).unwrap(),
661 conference_end: chrono::Utc.with_ymd_and_hms(2024, 5, 11, 18, 0, 0).unwrap(),
662 },
663 requirements: SubmissionRequirements {
664 page_limit: 9,
665 word_limit: None,
666 format: FormatRequirements {
667 template: "ICLR 2024 LaTeX template".to_string(),
668 font_size: 10,
669 line_spacing: 1.0,
670 margins: "1 inch".to_string(),
671 citation_style: "ICLR".to_string(),
672 file_format: vec!["PDF".to_string()],
673 },
674 required_sections: vec![
675 "Abstract".to_string(),
676 "Introduction".to_string(),
677 "Related Work".to_string(),
678 "Method".to_string(),
679 "Experiments".to_string(),
680 "Conclusion".to_string(),
681 ],
682 supplementary_allowed: true,
683 anonymous_submission: true,
684 double_blind: true,
685 },
686 review_process: ReviewProcess {
687 reviewers_per_paper: 3,
688 review_criteria: vec![
689 "Technical Quality".to_string(),
690 "Clarity".to_string(),
691 "Originality".to_string(),
692 "Significance".to_string(),
693 ],
694 rebuttal_allowed: true,
695 acceptance_rate: Some(0.31), review_format: ReviewFormat::Mixed,
697 },
698 }
699 }
700
701 fn create_aaai_conference() -> Conference {
702 Conference {
703 id: "aaai2024".to_string(),
704 name: "AAAI Conference on Artificial Intelligence".to_string(),
705 abbreviation: "AAAI".to_string(),
706 description: "Conference on artificial intelligence".to_string(),
707 url: "https://aaai.org/".to_string(),
708 ranking: ConferenceRanking::TopTier,
709 research_areas: vec![
710 "Artificial Intelligence".to_string(),
711 "Machine Learning".to_string(),
712 "Knowledge Representation".to_string(),
713 "Planning".to_string(),
714 ],
715 annual: true,
716 series_info: SeriesInfo {
717 series_number: 38,
718 year: 2024,
719 location: "Vancouver".to_string(),
720 country: "Canada".to_string(),
721 format: ConferenceFormat::Hybrid,
722 },
723 dates: ConferenceDates {
724 abstract_deadline: Some(
725 chrono::Utc
726 .with_ymd_and_hms(2023, 8, 15, 23, 59, 59)
727 .unwrap(),
728 ),
729 paper_deadline: chrono::Utc
730 .with_ymd_and_hms(2023, 8, 19, 23, 59, 59)
731 .unwrap(),
732 notification_date: chrono::Utc.with_ymd_and_hms(2023, 12, 9, 12, 0, 0).unwrap(),
733 camera_ready_deadline: chrono::Utc
734 .with_ymd_and_hms(2024, 1, 15, 23, 59, 59)
735 .unwrap(),
736 conference_start: chrono::Utc.with_ymd_and_hms(2024, 2, 20, 9, 0, 0).unwrap(),
737 conference_end: chrono::Utc.with_ymd_and_hms(2024, 2, 27, 18, 0, 0).unwrap(),
738 },
739 requirements: SubmissionRequirements {
740 page_limit: 7,
741 word_limit: None,
742 format: FormatRequirements {
743 template: "AAAI 2024 LaTeX template".to_string(),
744 font_size: 10,
745 line_spacing: 1.0,
746 margins: "0.75 inch".to_string(),
747 citation_style: "AAAI".to_string(),
748 file_format: vec!["PDF".to_string()],
749 },
750 required_sections: vec![
751 "Abstract".to_string(),
752 "Introduction".to_string(),
753 "Related Work".to_string(),
754 "Approach".to_string(),
755 "Experiments".to_string(),
756 "Conclusion".to_string(),
757 ],
758 supplementary_allowed: false,
759 anonymous_submission: true,
760 double_blind: true,
761 },
762 review_process: ReviewProcess {
763 reviewers_per_paper: 3,
764 review_criteria: vec![
765 "Technical Quality".to_string(),
766 "Novelty".to_string(),
767 "Significance".to_string(),
768 "Clarity".to_string(),
769 ],
770 rebuttal_allowed: false,
771 acceptance_rate: Some(0.23), review_format: ReviewFormat::NumericalScores,
773 },
774 }
775 }
776
777 fn create_ijcai_conference() -> Conference {
778 Conference {
779 id: "ijcai2024".to_string(),
780 name: "International Joint Conference on Artificial Intelligence".to_string(),
781 abbreviation: "IJCAI".to_string(),
782 description: "International conference on artificial intelligence".to_string(),
783 url: "https://ijcai.org/".to_string(),
784 ranking: ConferenceRanking::TopTier,
785 research_areas: vec![
786 "Artificial Intelligence".to_string(),
787 "Machine Learning".to_string(),
788 "Automated Reasoning".to_string(),
789 "Multi-agent Systems".to_string(),
790 ],
791 annual: true,
792 series_info: SeriesInfo {
793 series_number: 33,
794 year: 2024,
795 location: "Jeju".to_string(),
796 country: "South Korea".to_string(),
797 format: ConferenceFormat::Hybrid,
798 },
799 dates: ConferenceDates {
800 abstract_deadline: Some(
801 chrono::Utc
802 .with_ymd_and_hms(2024, 1, 17, 23, 59, 59)
803 .unwrap(),
804 ),
805 paper_deadline: chrono::Utc
806 .with_ymd_and_hms(2024, 1, 24, 23, 59, 59)
807 .unwrap(),
808 notification_date: chrono::Utc.with_ymd_and_hms(2024, 4, 16, 12, 0, 0).unwrap(),
809 camera_ready_deadline: chrono::Utc
810 .with_ymd_and_hms(2024, 5, 15, 23, 59, 59)
811 .unwrap(),
812 conference_start: chrono::Utc.with_ymd_and_hms(2024, 8, 3, 9, 0, 0).unwrap(),
813 conference_end: chrono::Utc.with_ymd_and_hms(2024, 8, 9, 18, 0, 0).unwrap(),
814 },
815 requirements: SubmissionRequirements {
816 page_limit: 7,
817 word_limit: None,
818 format: FormatRequirements {
819 template: "IJCAI 2024 LaTeX template".to_string(),
820 font_size: 10,
821 line_spacing: 1.0,
822 margins: "0.75 inch".to_string(),
823 citation_style: "IJCAI".to_string(),
824 file_format: vec!["PDF".to_string()],
825 },
826 required_sections: vec![
827 "Abstract".to_string(),
828 "Introduction".to_string(),
829 "Background".to_string(),
830 "Approach".to_string(),
831 "Experiments".to_string(),
832 "Conclusion".to_string(),
833 ],
834 supplementary_allowed: false,
835 anonymous_submission: true,
836 double_blind: true,
837 },
838 review_process: ReviewProcess {
839 reviewers_per_paper: 3,
840 review_criteria: vec![
841 "Technical Quality".to_string(),
842 "Novelty".to_string(),
843 "Significance".to_string(),
844 "Clarity".to_string(),
845 ],
846 rebuttal_allowed: true,
847 acceptance_rate: Some(0.15), review_format: ReviewFormat::Mixed,
849 },
850 }
851 }
852}
853
854#[cfg(test)]
855mod tests {
856 use super::*;
857
858 #[test]
859 fn test_conference_manager_creation() {
860 let manager = ConferenceManager::new();
861 assert!(manager.conferences.is_empty());
862 assert!(manager.submissions.is_empty());
863 }
864
865 #[test]
866 fn test_load_standard_conferences() {
867 let mut manager = ConferenceManager::new();
868 manager.load_standard_conferences();
869
870 assert!(manager.conferences.contains_key("neurips2024"));
871 assert!(manager.conferences.contains_key("icml2024"));
872 assert!(manager.conferences.contains_key("iclr2024"));
873 assert!(manager.conferences.contains_key("aaai2024"));
874 assert!(manager.conferences.contains_key("ijcai2024"));
875 }
876
877 #[test]
878 fn test_search_conferences() {
879 let mut manager = ConferenceManager::new();
880 manager.load_standard_conferences();
881
882 let ml_conferences = manager.search_conferences("Machine Learning");
883 assert!(!ml_conferences.is_empty());
884
885 let top_tier = manager.get_conferences_by_ranking(ConferenceRanking::TopTier);
886 assert!(!top_tier.is_empty());
887 }
888}