Skip to main content

optirs_core/research/
conferences.rs

1// Academic conference integration and submission tools
2//
3// This module provides tools for managing conference submissions,
4// tracking deadlines, and preparing submission materials.
5
6use crate::error::{OptimError, Result};
7use chrono::{DateTime, TimeZone, Utc};
8use serde::{Deserialize, Serialize};
9use std::collections::HashMap;
10
11/// Conference database and submission manager
12#[derive(Debug, Clone, Serialize, Deserialize)]
13pub struct ConferenceManager {
14    /// Known conferences
15    pub conferences: HashMap<String, Conference>,
16    /// Submission tracking
17    pub submissions: Vec<Submission>,
18    /// Deadline alerts
19    pub alerts: Vec<DeadlineAlert>,
20}
21
22/// Academic conference information
23#[derive(Debug, Clone, Serialize, Deserialize)]
24pub struct Conference {
25    /// Conference identifier
26    pub id: String,
27    /// Conference name
28    pub name: String,
29    /// Conference abbreviation
30    pub abbreviation: String,
31    /// Conference description
32    pub description: String,
33    /// Conference URL
34    pub url: String,
35    /// Conference ranking/tier
36    pub ranking: ConferenceRanking,
37    /// Research areas
38    pub research_areas: Vec<String>,
39    /// Annual occurrence
40    pub annual: bool,
41    /// Conference series information
42    pub series_info: SeriesInfo,
43    /// Important dates
44    pub dates: ConferenceDates,
45    /// Submission requirements
46    pub requirements: SubmissionRequirements,
47    /// Review process
48    pub review_process: ReviewProcess,
49}
50
51/// Conference ranking/tier
52#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
53pub enum ConferenceRanking {
54    /// Top-tier (A*)
55    TopTier,
56    /// High-quality (A)
57    HighQuality,
58    /// Good (B)
59    Good,
60    /// Acceptable (C)
61    Acceptable,
62    /// Emerging
63    Emerging,
64    /// Workshop
65    Workshop,
66    /// Unranked
67    Unranked,
68}
69
70/// Conference series information
71#[derive(Debug, Clone, Serialize, Deserialize)]
72pub struct SeriesInfo {
73    /// Series number (e.g., 35th)
74    pub series_number: u32,
75    /// Year
76    pub year: u32,
77    /// Location
78    pub location: String,
79    /// Country
80    pub country: String,
81    /// Conference format
82    pub format: ConferenceFormat,
83}
84
85/// Conference format
86#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
87pub enum ConferenceFormat {
88    /// In-person conference
89    InPerson,
90    /// Virtual conference
91    Virtual,
92    /// Hybrid conference
93    Hybrid,
94}
95
96/// Important conference dates
97#[derive(Debug, Clone, Serialize, Deserialize)]
98pub struct ConferenceDates {
99    /// Abstract submission deadline
100    pub abstract_deadline: Option<DateTime<Utc>>,
101    /// Paper submission deadline
102    pub paper_deadline: DateTime<Utc>,
103    /// Notification date
104    pub notification_date: DateTime<Utc>,
105    /// Camera-ready deadline
106    pub camera_ready_deadline: DateTime<Utc>,
107    /// Conference start date
108    pub conference_start: DateTime<Utc>,
109    /// Conference end date
110    pub conference_end: DateTime<Utc>,
111}
112
113/// Submission requirements
114#[derive(Debug, Clone, Serialize, Deserialize)]
115pub struct SubmissionRequirements {
116    /// Page limit
117    pub page_limit: u32,
118    /// Word limit
119    pub word_limit: Option<u32>,
120    /// Format requirements
121    pub format: FormatRequirements,
122    /// Required sections
123    pub required_sections: Vec<String>,
124    /// Supplementary material allowed
125    pub supplementary_allowed: bool,
126    /// Anonymous submission required
127    pub anonymous_submission: bool,
128    /// Double-blind review
129    pub double_blind: bool,
130}
131
132/// Format requirements
133#[derive(Debug, Clone, Serialize, Deserialize)]
134pub struct FormatRequirements {
135    /// Document template
136    pub template: String,
137    /// Font size
138    pub font_size: u32,
139    /// Line spacing
140    pub line_spacing: f64,
141    /// Margins
142    pub margins: String,
143    /// Citation style
144    pub citation_style: String,
145    /// File format
146    pub file_format: Vec<String>,
147}
148
149/// Review process information
150#[derive(Debug, Clone, Serialize, Deserialize)]
151pub struct ReviewProcess {
152    /// Number of reviewers per paper
153    pub reviewers_per_paper: u32,
154    /// Review criteria
155    pub review_criteria: Vec<String>,
156    /// Rebuttal allowed
157    pub rebuttal_allowed: bool,
158    /// Acceptance rate (if known)
159    pub acceptance_rate: Option<f64>,
160    /// Review format
161    pub review_format: ReviewFormat,
162}
163
164/// Review format
165#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
166pub enum ReviewFormat {
167    /// Numerical scores
168    NumericalScores,
169    /// Written reviews only
170    WrittenOnly,
171    /// Mixed format
172    Mixed,
173}
174
175/// Conference submission
176#[derive(Debug, Clone, Serialize, Deserialize)]
177pub struct Submission {
178    /// Submission ID
179    pub id: String,
180    /// Conference ID
181    pub conference_id: String,
182    /// Paper/publication ID
183    pub paper_id: String,
184    /// Submission status
185    pub status: SubmissionStatus,
186    /// Submission date
187    pub submitted_at: DateTime<Utc>,
188    /// Track/category
189    pub track: Option<String>,
190    /// Submission materials
191    pub materials: SubmissionMaterials,
192    /// Review information
193    pub reviews: Vec<Review>,
194    /// Decision information
195    pub decision: Option<Decision>,
196}
197
198/// Submission status
199#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
200pub enum SubmissionStatus {
201    /// Draft
202    Draft,
203    /// Submitted
204    Submitted,
205    /// Under review
206    UnderReview,
207    /// Rebuttal period
208    Rebuttal,
209    /// Decision made
210    Decided,
211    /// Camera-ready submitted
212    CameraReady,
213    /// Withdrawn
214    Withdrawn,
215}
216
217/// Submission materials
218#[derive(Debug, Clone, Serialize, Deserialize)]
219pub struct SubmissionMaterials {
220    /// Main paper file
221    pub paper_file: String,
222    /// Supplementary materials
223    pub supplementary_files: Vec<String>,
224    /// Abstract
225    pub abstracttext: String,
226    /// Keywords
227    pub keywords: Vec<String>,
228    /// Author information (if not anonymous)
229    pub authors: Option<Vec<String>>,
230}
231
232/// Review information
233#[derive(Debug, Clone, Serialize, Deserialize)]
234pub struct Review {
235    /// Review ID
236    pub id: String,
237    /// Reviewer (anonymous)
238    pub reviewer: String,
239    /// Overall score
240    pub overall_score: Option<f64>,
241    /// Detailed scores
242    pub detailed_scores: HashMap<String, f64>,
243    /// Written review
244    pub reviewtext: String,
245    /// Recommendation
246    pub recommendation: ReviewRecommendation,
247    /// Review date
248    pub reviewed_at: DateTime<Utc>,
249}
250
251/// Review recommendations
252#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
253pub enum ReviewRecommendation {
254    /// Strong accept
255    StrongAccept,
256    /// Accept
257    Accept,
258    /// Weak accept
259    WeakAccept,
260    /// Borderline
261    Borderline,
262    /// Weak reject
263    WeakReject,
264    /// Reject
265    Reject,
266    /// Strong reject
267    StrongReject,
268}
269
270/// Conference decision
271#[derive(Debug, Clone, Serialize, Deserialize)]
272pub struct Decision {
273    /// Decision outcome
274    pub outcome: DecisionOutcome,
275    /// Decision date
276    pub decided_at: DateTime<Utc>,
277    /// Editor comments
278    pub editor_comments: Option<String>,
279    /// Required revisions
280    pub required_revisions: Vec<String>,
281}
282
283/// Decision outcomes
284#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
285pub enum DecisionOutcome {
286    /// Accept
287    Accept,
288    /// Accept with minor revisions
289    AcceptMinorRevisions,
290    /// Accept with major revisions
291    AcceptMajorRevisions,
292    /// Conditional accept
293    ConditionalAccept,
294    /// Reject
295    Reject,
296    /// Reject and resubmit
297    RejectAndResubmit,
298}
299
300/// Deadline alert
301#[derive(Debug, Clone, Serialize, Deserialize)]
302pub struct DeadlineAlert {
303    /// Alert ID
304    pub id: String,
305    /// Conference ID
306    pub conference_id: String,
307    /// Deadline type
308    pub deadline_type: DeadlineType,
309    /// Alert date
310    pub alert_date: DateTime<Utc>,
311    /// Days before deadline
312    pub days_before: u32,
313    /// Alert message
314    pub message: String,
315    /// Alert sent
316    pub sent: bool,
317}
318
319/// Types of deadlines
320#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
321pub enum DeadlineType {
322    /// Abstract submission
323    AbstractSubmission,
324    /// Paper submission
325    PaperSubmission,
326    /// Notification
327    Notification,
328    /// Camera-ready
329    CameraReady,
330    /// Conference start
331    ConferenceStart,
332}
333
334impl Default for ConferenceManager {
335    fn default() -> Self {
336        Self::new()
337    }
338}
339
340impl ConferenceManager {
341    /// Create a new conference manager
342    pub fn new() -> Self {
343        Self {
344            conferences: HashMap::new(),
345            submissions: Vec::new(),
346            alerts: Vec::new(),
347        }
348    }
349
350    /// Add a conference to the database
351    pub fn add_conference(&mut self, conference: Conference) {
352        self.conferences.insert(conference.id.clone(), conference);
353    }
354
355    /// Submit a paper to a conference
356    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    /// Get upcoming deadlines
387    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        // Sort by deadline date
442        deadlines.sort_by_key(|a| a.2);
443        deadlines
444    }
445
446    /// Search conferences by research area
447    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    /// Get conferences by ranking
459    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    /// Create standard ML/AI conferences
467    pub fn load_standard_conferences(&mut self) {
468        // Add some well-known conferences
469        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), // Approximately 26%
559                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), // Approximately 23%
641                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), // Approximately 31%
729                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), // Approximately 23%
817                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), // Approximately 15%
905                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}