optirs_core/research/
funding.rs1use serde::{Deserialize, Serialize};
2use std::collections::HashMap;
3
4#[derive(Debug, Clone, Serialize, Deserialize)]
6pub struct FundingSource {
7 pub id: String,
8 pub name: String,
9 pub agency: String,
10 pub program: Option<String>,
11 pub grant_number: Option<String>,
12 pub amount: Option<f64>,
13 pub currency: String,
14 pub start_date: Option<chrono::DateTime<chrono::Utc>>,
15 pub end_date: Option<chrono::DateTime<chrono::Utc>>,
16}
17
18#[derive(Debug, Clone, Serialize, Deserialize)]
20pub struct Grant {
21 pub id: String,
22 pub title: String,
23 pub abstract_text: Option<String>,
24 pub principal_investigator: String,
25 pub co_investigators: Vec<String>,
26 pub funding_source: FundingSource,
27 pub status: GrantStatus,
28}
29
30#[derive(Debug, Clone, Serialize, Deserialize)]
32pub enum GrantStatus {
33 Draft,
34 Submitted,
35 UnderReview,
36 Awarded,
37 Rejected,
38 Active,
39 Completed,
40}
41
42#[derive(Debug, Default)]
44pub struct FundingManager {
45 grants: HashMap<String, Grant>,
46 funding_sources: HashMap<String, FundingSource>,
47}
48
49impl FundingManager {
50 pub fn new() -> Self {
51 Self {
52 grants: HashMap::new(),
53 funding_sources: HashMap::new(),
54 }
55 }
56
57 pub fn add_grant(&mut self, grant: Grant) {
58 self.grants.insert(grant.id.clone(), grant);
59 }
60
61 pub fn get_grant(&self, id: &str) -> Option<&Grant> {
62 self.grants.get(id)
63 }
64
65 pub fn add_funding_source(&mut self, source: FundingSource) {
66 self.funding_sources.insert(source.id.clone(), source);
67 }
68
69 pub fn get_funding_source(&self, id: &str) -> Option<&FundingSource> {
70 self.funding_sources.get(id)
71 }
72
73 pub fn list_active_grants(&self) -> Vec<&Grant> {
74 self.grants
75 .values()
76 .filter(|g| matches!(g.status, GrantStatus::Active))
77 .collect()
78 }
79}