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(|a, b| a.2.cmp(&b.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                        .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), // Approximately 26%
549                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), // Approximately 23%
620                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), // Approximately 31%
696                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), // Approximately 23%
772                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), // Approximately 15%
848                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}