Решение на упр.03 задача 3 от Димитър Николов
Към профила на Димитър Николов
Резултати
- 2 точки от тестове
- 0 бонус точки
- 2 точки общо
- 2 успешни тест(а)
- 0 неуспешни тест(а)
Код
use std::collections::HashMap;
enum Event {
    Login {
        user: String,
        timestamp: u64,
    },
    Logout {
        user: String,
        timestamp: u64,
    },
    Purchase {
        user: String,
        item: String,
        amount: f64,
        timestamp: u64,
    },
    Error {
        code: i32,
        message: String,
        timestamp: u64,
    },
}
struct EventLog {
    events: Vec<Event>,
}
impl Event {
    const LOGIN: &str = "Login";
    const LOGOUT: &str = "Logout";
    const PURCHASE: &str = "Purchase";
    const ERROR: &str = "Error";
    fn name(&self) -> &'static str {
        match self {
            Event::Login { .. } => Event::LOGIN,
            Event::Logout { .. } => Event::LOGOUT,
            Event::Purchase { .. } => Event::PURCHASE,
            Event::Error { .. } => Event::ERROR,
        }
    }
    fn spending(&self) -> Option<&f64> {
        match self {
            Event::Purchase { amount, .. } => Some(amount),
            Event::Login { .. } | Event::Logout { .. } | Event::Error { .. } => None,
        }
    }
    fn is_from_user(&self, user: Option<&str>) -> bool {
        let Some(user) = user else {
            return true;
        };
        let self_user = match self {
            Event::Login { user, .. } => user,
            Event::Logout { user, .. } => user,
            Event::Purchase { user, .. } => user,
            Event::Error { .. } => return false,
        };
        self_user == user
    }
    fn is_after(&self, timestamp: Option<u64>) -> bool {
        let Some(timestamp) = timestamp else {
            return true;
        };
        let self_timestamp = match self {
            Event::Login { timestamp, .. } => timestamp,
            Event::Logout { timestamp, .. } => timestamp,
            Event::Purchase { timestamp, .. } => timestamp,
            Event::Error { timestamp, .. } => timestamp,
        };
        *self_timestamp >= timestamp
    }
}
impl EventLog {
    fn new() -> Self {
        Self { events: vec![] }
    }
    fn add_event(&mut self, event: Event) {
        self.events.push(event)
    }
    fn user_spent(&self, user: &str) -> f64 {
        self.events
            .iter()
            .filter(|event| event.is_from_user(Some(user)))
            .map(|event| event.spending())
            .flatten()
            .sum()
    }
    fn summaries_by_type(&self) -> HashMap<String, usize> {
        self.events
            .iter()
            .map(|event| event.name())
            .fold(HashMap::new(), |mut map, event| {
                *map.entry(event.to_string()).or_insert(0) += 1;
                map
            })
    }
    fn filter_events(&self, user: Option<&str>, after: Option<u64>) -> Vec<&Event> {
        self.events
            .iter()
            .filter(|event| event.is_from_user(user))
            .filter(|event| event.is_after(after))
            .collect()
    }
}
Лог от изпълнението
Updating crates.io index
     Locking 17 packages to latest compatible versions
   Compiling proc-macro2 v1.0.103
   Compiling unicode-ident v1.0.22
   Compiling quote v1.0.41
   Compiling futures-sink v0.3.31
   Compiling futures-core v0.3.31
   Compiling futures-channel v0.3.31
   Compiling futures-task v0.3.31
   Compiling pin-utils v0.1.0
   Compiling syn v2.0.108
   Compiling slab v0.4.11
   Compiling memchr v2.7.6
   Compiling pin-project-lite v0.2.16
   Compiling futures-io v0.3.31
   Compiling solution v0.1.0 (/tmp/d20251030-1757769-8kmijn/solution)
warning: enum `Event` is never used
 --> src/lib.rs:3:6
  |
3 | enum Event {
  |      ^^^^^
  |
  = note: `#[warn(dead_code)]` on by default
warning: struct `EventLog` is never constructed
  --> src/lib.rs:25:8
   |
25 | struct EventLog {
   |        ^^^^^^^^
warning: multiple associated items are never used
  --> src/lib.rs:30:11
   |
29 | impl Event {
   | ---------- associated items in this implementation
30 |     const LOGIN: &str = "Login";
   |           ^^^^^
31 |     const LOGOUT: &str = "Logout";
   |           ^^^^^^
32 |     const PURCHASE: &str = "Purchase";
   |           ^^^^^^^^
33 |     const ERROR: &str = "Error";
   |           ^^^^^
34 |
35 |     fn name(&self) -> &'static str {
   |        ^^^^
...
44 |     fn spending(&self) -> Option<&f64> {
   |        ^^^^^^^^
...
51 |     fn is_from_user(&self, user: Option<&str>) -> bool {
   |        ^^^^^^^^^^^^
...
66 |     fn is_after(&self, timestamp: Option<u64>) -> bool {
   |        ^^^^^^^^
warning: associated items `new`, `add_event`, `user_spent`, `summaries_by_type`, and `filter_events` are never used
   --> src/lib.rs:83:8
    |
82  | impl EventLog {
    | ------------- associated items in this implementation
83  |     fn new() -> Self {
    |        ^^^
...
87  |     fn add_event(&mut self, event: Event) {
    |        ^^^^^^^^^
...
91  |     fn user_spent(&self, user: &str) -> f64 {
    |        ^^^^^^^^^^
...
100 |     fn summaries_by_type(&self) -> HashMap<String, usize> {
    |        ^^^^^^^^^^^^^^^^^
...
110 |     fn filter_events(&self, user: Option<&str>, after: Option<u64>) -> Vec<&Event> {
    |        ^^^^^^^^^^^^^
warning: `solution` (lib) generated 4 warnings
   Compiling futures-macro v0.3.31
   Compiling futures-util v0.3.31
   Compiling futures-executor v0.3.31
   Compiling futures v0.3.31
    Finished `test` profile [unoptimized + debuginfo] target(s) in 8.72s
     Running tests/solution_test.rs (target/debug/deps/solution_test-bfd50394249726db)
running 2 tests
test solution_test::test_empty ... ok
test solution_test::test_basic ... ok
test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
История (3 версии и 0 коментара)
Димитър качи решение на 23.10.2025 19:50 (преди 8 дена)
 use std::collections::HashMap;
 enum Event {
     Login {
         user: String,
         timestamp: u64,
     },
     Logout {
         user: String,
         timestamp: u64,
     },
     Purchase {
         user: String,
         item: String,
         amount: f64,
         timestamp: u64,
     },
     Error {
         code: i32,
         message: String,
         timestamp: u64,
     },
 }
 struct EventLog {
     events: Vec<Event>,
 }
 impl Event {
     const LOGIN: &str = "Login";
     const LOGOUT: &str = "Logout";
     const PURCHASE: &str = "Purchase";
     const ERROR: &str = "Error";
     fn name(&self) -> &'static str {
         match self {
             Event::Login {
                 user: _,
                 timestamp: _,
             } => Event::LOGIN,
             Event::Logout {
                 user: _,
                 timestamp: _,
             } => Event::LOGOUT,
             Event::Purchase {
                 user: _,
                 item: _,
                 amount: _,
                 timestamp: _,
             } => Event::PURCHASE,
             Event::Error {
                 code: _,
                 message: _,
                 timestamp: _,
             } => Event::ERROR,
         }
     }
     fn spending(&self) -> Option<&f64> {
         match self {
             Event::Purchase {
                 user: _,
                 item: _,
                 amount,
                 timestamp: _,
             } => Some(amount),
             _ => None,
         }
     }
     fn is_from_user(&self, user: Option<&str>) -> bool {
-        if user.is_none() {
-            return false;
-        }
+        let Some(user) = user else {
+            return true;
+        };
-        let usr = match (self) {
+        let self_user = match self {
             Event::Login { user, timestamp: _ } => user,
             Event::Logout { user, timestamp: _ } => user,
             Event::Purchase {
                 user,
                 item: _,
                 amount: _,
                 timestamp: _,
             } => user,
             Event::Error {
                 code: _,
                 message: _,
                 timestamp: _,
-            } => return false,
+            } => return true,
         };
-        usr == user.unwrap()
+        self_user == user
     }
     fn is_after(&self, timestamp: Option<u64>) -> bool {
-        if timestamp.is_none() {
-            return false;
-        }
+        let Some(timestamp) = timestamp else {
+            return true;
+        };
-        let ts = match (self) {
+        let self_timestamp = match self {
             Event::Login { user: _, timestamp } => timestamp,
             Event::Logout { user: _, timestamp } => timestamp,
             Event::Purchase {
                 user: _,
                 item: _,
                 amount: _,
                 timestamp,
             } => timestamp,
             Event::Error {
                 code: _,
                 message: _,
                 timestamp,
             } => timestamp,
         };
-        *ts > timestamp.unwrap()
+        *self_timestamp > timestamp
     }
 }
 impl EventLog {
     fn new() -> Self {
         Self { events: vec![] }
     }
     fn add_event(&mut self, event: Event) {
         self.events.push(event)
     }
     fn user_spent(&self, user: &str) -> f64 {
         self.events
             .iter()
+            .filter(|event| event.is_from_user(Some(user)))
             .map(|event| event.spending())
             .flatten()
             .sum()
     }
     fn summaries_by_type(&self) -> HashMap<String, usize> {
         let initial_map = HashMap::from([
             (String::from(Event::LOGIN), 0),
             (String::from(Event::LOGOUT), 0),
             (String::from(Event::PURCHASE), 0),
             (String::from(Event::ERROR), 0),
         ]);
         self.events
             .iter()
             .map(|event| event.name())
             .fold(initial_map, |mut map, event| {
                 *map.get_mut(event).unwrap() += 1;
                 map
             })
     }
     fn filter_events(&self, user: Option<&str>, after: Option<u64>) -> Vec<&Event> {
         self.events
             .iter()
-            .filter(|event| event.is_after(after))
             .filter(|event| event.is_from_user(user))
+            .filter(|event| event.is_after(after))
             .collect()
     }
 }
Димитър качи решение на 25.10.2025 16:01 (преди 6 дена)
 use std::collections::HashMap;
 enum Event {
     Login {
         user: String,
         timestamp: u64,
     },
     Logout {
         user: String,
         timestamp: u64,
     },
     Purchase {
         user: String,
         item: String,
         amount: f64,
         timestamp: u64,
     },
     Error {
         code: i32,
         message: String,
         timestamp: u64,
     },
 }
 struct EventLog {
     events: Vec<Event>,
 }
 impl Event {
     const LOGIN: &str = "Login";
     const LOGOUT: &str = "Logout";
     const PURCHASE: &str = "Purchase";
     const ERROR: &str = "Error";
     fn name(&self) -> &'static str {
         match self {
-            Event::Login {
-                user: _,
-                timestamp: _,
-            } => Event::LOGIN,
-            Event::Logout {
-                user: _,
-                timestamp: _,
-            } => Event::LOGOUT,
-            Event::Purchase {
-                user: _,
-                item: _,
-                amount: _,
-                timestamp: _,
-            } => Event::PURCHASE,
-            Event::Error {
-                code: _,
-                message: _,
-                timestamp: _,
-            } => Event::ERROR,
+            Event::Login { .. } => Event::LOGIN,
+            Event::Logout { .. } => Event::LOGOUT,
+            Event::Purchase { .. } => Event::PURCHASE,
+            Event::Error { .. } => Event::ERROR,
         }
     }
     fn spending(&self) -> Option<&f64> {
         match self {
-            Event::Purchase {
-                user: _,
-                item: _,
-                amount,
-                timestamp: _,
-            } => Some(amount),
-            _ => None,
+            Event::Purchase { amount, .. } => Some(amount),
+            Event::Login { .. } | Event::Logout { .. } | Event::Error { .. } => None,
         }
     }
     fn is_from_user(&self, user: Option<&str>) -> bool {
         let Some(user) = user else {
             return true;
         };
         let self_user = match self {
-            Event::Login { user, timestamp: _ } => user,
-            Event::Logout { user, timestamp: _ } => user,
-            Event::Purchase {
-                user,
-                item: _,
-                amount: _,
-                timestamp: _,
-            } => user,
-            Event::Error {
-                code: _,
-                message: _,
-                timestamp: _,
-            } => return true,
+            Event::Login { user, .. } => user,
+            Event::Logout { user, .. } => user,
+            Event::Purchase { user, .. } => user,
+            Event::Error { .. } => return false,
         };
         self_user == user
     }
     fn is_after(&self, timestamp: Option<u64>) -> bool {
         let Some(timestamp) = timestamp else {
             return true;
         };
         let self_timestamp = match self {
-            Event::Login { user: _, timestamp } => timestamp,
-            Event::Logout { user: _, timestamp } => timestamp,
-            Event::Purchase {
-                user: _,
-                item: _,
-                amount: _,
-                timestamp,
-            } => timestamp,
-            Event::Error {
-                code: _,
-                message: _,
-                timestamp,
-            } => timestamp,
+            Event::Login { timestamp, .. } => timestamp,
+            Event::Logout { timestamp, .. } => timestamp,
+            Event::Purchase { timestamp, .. } => timestamp,
+            Event::Error { timestamp, .. } => timestamp,
         };
-        *self_timestamp > timestamp
+        *self_timestamp >= timestamp
     }
 }
 impl EventLog {
     fn new() -> Self {
         Self { events: vec![] }
     }
     fn add_event(&mut self, event: Event) {
         self.events.push(event)
     }
     fn user_spent(&self, user: &str) -> f64 {
         self.events
             .iter()
             .filter(|event| event.is_from_user(Some(user)))
             .map(|event| event.spending())
             .flatten()
             .sum()
     }
     fn summaries_by_type(&self) -> HashMap<String, usize> {
-        let initial_map = HashMap::from([
-            (String::from(Event::LOGIN), 0),
-            (String::from(Event::LOGOUT), 0),
-            (String::from(Event::PURCHASE), 0),
-            (String::from(Event::ERROR), 0),
-        ]);
-
         self.events
             .iter()
             .map(|event| event.name())
-            .fold(initial_map, |mut map, event| {
-                *map.get_mut(event).unwrap() += 1;
+            .fold(HashMap::new(), |mut map, event| {
+                *map.entry(event.to_string()).or_insert(0) += 1;
                 map
             })
     }
     fn filter_events(&self, user: Option<&str>, after: Option<u64>) -> Vec<&Event> {
         self.events
             .iter()
             .filter(|event| event.is_from_user(user))
             .filter(|event| event.is_after(after))
             .collect()
     }
 }
