StopClock

For a long time now I wanted to do more rust related content. I have quite some ideas up mys sleeve, however, where to start? Because It has been a while that I did some coding I’ve decided to return to the roots or rather to my first written rust program. StopClock.

The name is terrible and not in the rust typical favor. However, this little program has become significant to me. I use it almost every day to get myself on a task or to tell me when something is over. Even now it tells me when the next focus time is over.

Here it is:

extern crate datetime;

use std::env::args;
use std::{thread, time};
use std::process::Command;
use datetime::{LocalDate, Month, DatePiece};

const MINUTE: u64= 60;

fn main() {
    let args: Vec<String>  = args().collect();


    
    if (args.len() == 2)
    {
      let name = &args[0];
      let time_to_sleep_arg = &args[1].clone();
      // This create some odd situation. you'll be hit with a Result<T,E> document.
      // not quite sure how to handle this. Seems like a struct with the std::String:Result 
      // The main question is, how to get this right? 
      // With Beni:
      // unwrap() would be possible 

      // The error is i use collect and trigger some nosense. 
      let time_to_sleep_arg2 = &args[1];

      println!("Going to sleep for: {} seconds at .", time_to_sleep_arg);

      let time_to_sleep  :u64 = match time_to_sleep_arg.trim().parse() {
        Ok(v)  => v,
        Err(_) => {panic!("Sorry we need to have number only")},
      };
    
        let mut remaining_time = time_to_sleep;
        let mut time_as_minutes  = 0;
 
        while (remaining_time >= MINUTE){
          remaining_time = remaining_time - MINUTE;
          time_as_minutes = time_as_minutes + 1;

        }
        println!("More than 1 Minute!");
        println!("Going to sleep for {} Minutes!", time_as_minutes);
     
       let mut minutes_remaining = 0;
        while(minutes_remaining != time_as_minutes)
        {
          minutes_remaining = minutes_remaining + 1;
          let second = time::Duration::from_secs(60);
          thread::sleep(second);
          println!("Going to sleep for {} more Minutes", time_as_minutes - minutes_remaining );
        }
        // sleep the remaining time
        let remaining_second = time::Duration::from_secs(remaining_time);
        thread::sleep(remaining_second);

        Command::new("/usr/bin/notify-send")
                .args(&["-u", "normal", "-t", "15000", "StopClock", "Times up!"]) 
                .output();

        // https://doc.rust-lang.org/std/process/struct.Command.html
        Command::new("/usr/bin/mplayer")
                 .args(&["-volume","50", "/home/akendo/Downloads/end.mp3"])
                 .output();
       
    } 
    else 
    {
      println!("Please add only one  argument!");
    }
}

I feel a bit awkward, however, it was my first program that I developed in rust. Now we’re going to change it a bit. To be completely honest with you, I’ve changed it in between a bit because I added some improvements.

But what needs to be done here?

But lately, I’ve seen the follow issue for me: A way to store the data and a way to have it count upwards. Why?

I think this should reflect the task a bit more, when you do something present seen how much time you’ve spent on it feel better. And seeing how much time is left on a task that you have to do feels more relieving. It should also track how much time was spending on things, but I’m most likely going to put this into the time warrior.

One further problem does this program have: It cannot handle time jumps. This is sometimes handy, but often annoying. What does this mean? For instance, when you suspend the laptop, the program going to continue to count disregard of the time that has come to pass.

Sometimes you close the lid of your devices to move on. Hence, it would be neat to keep track of the underlying system time instead of just.

But at first, I’m going to clean up the code before we’re going further.


warning: 9 warnings emitted

    Finished dev [unoptimized + debuginfo] target(s) in 0.01s

Gosh there are quite some warning. The compiler has improved a lot in the last four years!

Let’s go by them warning for warning:

Warning one: unused imports datetime

warning: unused imports: `DatePiece`, `LocalDate`, `Month`
 --> src/main.rs:6:16                                                      |                                                                      
6 | use datetime::{LocalDate, Month, DatePiece};
  |                ^^^^^^^^^  ^^^^^  ^^^^^^^^^          
  |
  = note: `#[warn(unused_imports)]` on by default

This related to some attempt at the beginning of the program to fix to suspend the issue. For now, we’re going to remove the datatime import until we have a good idea of how to keep track of it correctly.

Seeing this already pops an idea into my head: Get the current time, add the time the program have to wait and check the time once the while loop is completed. But one thing after another.

While disabling the import, I saw the variable in the next line. I am also going to change the size of MINUTE that is just below the import. An u64 huge to represent a two-digit number, I think. u8 should enough.

This will trigger some more error message now:

error[E0308]: mismatched types                                                                                                                     
  --> src/main.rs:38:45                                                                                                                            
   |                                                                                                                                               
38 |           remaining_time = remaining_time - MINUTE;                                                                                           
   |                                             ^^^^^^ expected `u64`, found `u8`
                                    
error[E0277]: cannot subtract `u8` from `u64`                                                                                                      
  --> src/main.rs:38:43
   |                                                                     
38 |           remaining_time = remaining_time - MINUTE;
   |                                           ^ no implementation for `u64 - u8`
   |                   
   = help: the trait `Sub<u8>` is not implemented for `u64`
                                                           

Obviously, this make sense since we’ve changed the size it becomes necessary to change it to the right size. Here is a good question, would it be not worth it to stick the u64 instead?

Hm… this is why having this written on the blog is awesome! Now I’m asking myself: What’s the benefit of saving a variable in a more effective size format vs. having perhaps more operations to convert it! My guess here is that it would be no more operation for the CPU because the C compiler only going to change the point internally, hence, it should be no different. But that’s a guess and I might need to search for this later on.

For the program we’re running this does matter anyway, however, this is an interesting question. Anyhow, here is what needs to be changed:

-        while (remaining_time >= MINUTE){
-          remaining_time = remaining_time - MINUTE;
+        while (remaining_time >= MINUTE as u64){
+          remaining_time = remaining_time - MINUTE as u64;

I’m going to continue with this next week.

so far,
akendo