thisweek_core/
year.rs

1use crate::calendar::Calendar;
2use crate::config;
3use crate::db_sqlite;
4use crate::language::Language;
5use crate::ordering::Result;
6use crate::prelude::Result as AppResult;
7use crate::today;
8use crate::{models::*, ordering::Ordering};
9use serde::Serialize;
10
11const MAIN_CALENDAR: u32 = 0;
12const SECONDARY_CALENDAR: u32 = 1;
13
14#[derive(Debug, Default)]
15pub struct Year {
16    pub reference_year: i32,
17    pub reference_calendar: u32,
18    pub calendar: Calendar,
19    pub language: Language,
20    pub items: Vec<Item>,
21
22    // for view only
23    pub year_view: YearView,
24}
25
26#[derive(Serialize, Clone, Debug, Default)]
27pub struct YearView {
28    pub year: String,
29    pub title: String,
30    pub info: String,
31    pub items: Vec<ItemView>,
32}
33
34impl Year {
35    pub fn new() -> Year {
36        let mut year = Year {
37            reference_calendar: MAIN_CALENDAR,
38            ..Default::default()
39        };
40        let _ = year.current();
41        year
42    }
43
44    pub fn update(&mut self) -> Result<()> {
45        let main_pair = config::get_main_cal_lang_pair();
46        let second_pair = config::get_second_cal_lang_pair();
47        if self.reference_calendar == SECONDARY_CALENDAR && second_pair.is_some() {
48            self.calendar = second_pair.clone().unwrap().calendar;
49            self.language = second_pair.unwrap().language;
50        } else {
51            // MAIN_CALENDAR
52            self.calendar = main_pair.calendar;
53            self.language = main_pair.language;
54        }
55
56        // update items
57        let items = db_sqlite::read_items_in_calendar_year(
58            self.calendar.clone().into(),
59            self.reference_year,
60        )?;
61        self.items = items;
62        self.check_and_fix_ordering();
63
64        // update yearly view
65        self.update_year_title_info();
66        self.year_view.items = self.items.iter().map(ItemView::from).collect();
67        Ok(())
68    }
69
70    pub fn get_view(&self) -> YearView {
71        self.year_view.clone()
72    }
73
74    pub fn get_calendar(&self) -> &Calendar {
75        &self.calendar
76    }
77
78    fn update_year_title_info(&mut self) {
79        self.year_view.year = self.reference_year.to_string();
80        self.year_view.year = self.language.change_numbers_language(&self.year_view.year);
81        self.year_view.title = match self.language {
82            Language::English => format!("Year {}", self.year_view.year),
83            Language::Farsi => format!("سال {}", self.year_view.year),
84            Language::Chinese => format!("{} 年", self.year_view.year),
85            Language::Arabic => format!("{} سنة", self.year_view.year),
86        };
87        self.year_view.info = String::new();
88    }
89
90    #[allow(clippy::should_implement_trait)]
91    pub fn next(&mut self) -> Result<()> {
92        self.reference_year += 1;
93        self.update()
94    }
95
96    pub fn previous(&mut self) -> Result<()> {
97        self.reference_year -= 1;
98        self.update()
99    }
100
101    pub fn current(&mut self) -> Result<()> {
102        self.reference_year = today::get_today_date(&self.calendar).year;
103        self.update()
104    }
105
106    pub fn add_new_item(
107        &mut self,
108        kind: i32,
109        text: String,
110        after_id: Option<i32>,
111    ) -> AppResult<i32> {
112        let current_year_calendar: Calendar = self.calendar.clone();
113        let calendar: i32 = current_year_calendar.into();
114        let year = Some(self.reference_year);
115        let ordering_key: String = self.get_new_ordering_key(after_id);
116        let new_item = NewItem::new(
117            calendar,
118            year,
119            None, //season,
120            None, //month,
121            0,    //day,
122            kind,
123            text,
124            ordering_key,
125        );
126        db_sqlite::create_item(&new_item)
127    }
128
129    pub fn switch_calendar(&mut self) -> Result<()> {
130        let main_cal: Calendar = config::get_config().main_calendar_type.into();
131        let aux_cal: Option<Calendar> = config::get_config()
132            .secondary_calendar_type
133            .map(|s| s.into());
134        if self.reference_calendar == MAIN_CALENDAR && aux_cal.is_some() {
135            self.reference_calendar = SECONDARY_CALENDAR;
136            self.calendar = aux_cal.unwrap();
137        } else {
138            self.reference_calendar = MAIN_CALENDAR;
139            self.calendar = main_cal;
140        }
141        // self.update()
142        self.current()
143    }
144
145    pub fn move_item_to_other_time_period_offset(&mut self, id: i32, offset: i32) -> Result<usize> {
146        if let Some(pos) = self.items.iter().position(|item| item.id == id) {
147            let mut item = self.items[pos].clone();
148            let year = item.year.unwrap_or(self.reference_year) + offset;
149            item.year = Some(year);
150            item.order_in_resolution = None;
151            let result = db_sqlite::update_item(&item);
152            let _ = self.update();
153            result
154        } else {
155            let _ = self.update();
156            Err("id not in list!".into())
157        }
158    }
159}
160
161impl Ordering for Year {
162    fn get_keys(&self) -> Vec<Option<String>> {
163        self.items
164            .iter()
165            .map(|i| i.order_in_resolution.clone())
166            .collect()
167    }
168
169    // fn get_ordering_key_of_posision(&self, i: usize) -> Result<Option<String>> {
170    //     Ok(self.items.get(i)?.order_in_resolution.clone())
171    // }
172
173    fn set_ordering_key_of_posision(&mut self, i: usize, key: Option<String>) -> Result<()> {
174        self.items
175            .get_mut(i)
176            .ok_or("invalid pos".to_string())?
177            .order_in_resolution = key;
178        Ok(())
179    }
180
181    // fn get_posision_of_id(&self, id: i32) -> Result<usize> {
182    //     self.items.iter().position(|item| item.id == id)
183    // }
184
185    fn get_ordering_key_of_id(&self, id: i32) -> Option<Option<String>> {
186        let pos = self.items.iter().position(|item| item.id == id)?;
187        Some(self.items.get(pos).unwrap().order_in_resolution.clone())
188    }
189
190    fn new_ordering_finished(&self) {
191        let _ = db_sqlite::update_items(&self.items);
192    }
193}