[Opinion on Project] Diagnosis system based on robot's logs file

#1

Hey everyone !

I’m quite new to rust language. That’s why I would like your opinion on a project I would like to develop, especially on the data structure to implement and to be sure I fully understand the logic under Rust language.

I don’t have much except some idea and simple POC of the data structure.

Disclamer: my naming skill is not as sharp as I would like… Sorry about that … :expressionless:

[Context]
I would like to do a sort of robot diagnosis system based on log file. The based idea might sound weird for you, but at least I have something to develop to learn Rust :slight_smile:.

The idea is to parse the log file created by the robot and create a data structure which can be used for multiple things like diagnosis, plotting, detect error signature, etc… I don’t know if all will be possible.

[Reflextion Time]
The robot is based on a state machin, so , I though to base my data structure around this state machine. For the example, let’s take two states with sub state:

  • Climbing : Up/Down

  • Driving: Drive/Stop

I created the enum like so:

#[derive(Debug)]
enum ClimbingState {
    Up,
    Down,
}
 #[derive(Debug)]
enum DrivingState {
    Drive,
    Stop,
}

As I work around the state of the robot, I thought to have a vector of a struct Data with all the data inside (Position & velocity with timestamps, errors occurred during the State, etc…). To specify the state, I made the structure generic with takes a state enum as the generic parameter.
To keep the code simple, the data is represented with only one i16, and the sub-state.

#[derive(Debug)]
    struct Data<T> {
        x: i16,
        state: T
    }
    // call example: 
    let a : Data<ClimbingState> = Data{x: 99 , state : ClimbingState::Up};

Like that I can implement some traits specifically to a State.

trait StateProcess {
    fn show(&self);

    fn add(&mut self);
}

impl StateProcess for Data<ClimbingState> {
    fn show(&self) {
        println!("{:?}", self.x);
    }

    fn add(&mut self){
        self.x += 1;
    }
}

impl StateProcess for Data<DrivingState> {
    fn show(&self) {
        println!("{:?}", self.x);
    }

    fn add(&mut self){
        self.x += 10;
    }
}

To put all the stuct inside a same vector, I wrapp the struct inside another enum like so:

#[derive(Debug)]
enum State {
    Climbing (Data<ClimbingState>),
    Driving (Data<DrivingState>),
}

But to get access to the data, I had to write

impl StateProcess for State {
    fn show(&self) {
        match self {
            State::Climbing(ref data) => data.show(),
            State::Driving(ref data) => data.show(),
        }
    }

    fn add(&mut self){
        match self {
            State::Climbing(ref mut data) => data.add(),
            State::Driving(ref mut data) => data.add(),
        }
    }
}

In the end, my main look like this

fn main() {

    let mut v = Vec::new();

    v.push(State::Climbing(Data{x: 10 , sta : ClimbingState::Up}));
    v.push(State::Driving(Data{x: 16 , sta : DrivingState::Stop}));

     for mut p in v {
         p.add();
         p.show();
     }
}

All the code down here

Summary
#[derive(Debug)]
enum State {
    Climbing (Data<ClimbingState>),
    Driving (Data<DrivingState>),
}

#[derive(Debug)]
enum ClimbingState {
    Up,
    Down,
}

#[derive(Debug)]
enum DrivingState {
    Stop,
    Drive,
}

#[derive(Debug)]
struct Data<T> {
    x: i16,
    sta: T
}

trait StateProcess {
    fn show(&self);

    fn add(&mut self);
}

impl StateProcess for Data<ClimbingState> {
    fn show(&self) {
        println!("{:?}", self.x);
    }

    fn add(&mut self){
        self.x += 1;
    }
}

impl StateProcess for Data<DrivingState> {
    fn show(&self) {
        println!("{:?}", self.x);
    }

    fn add(&mut self){
        self.x += 10;
    }
}

impl StateProcess for State {
    fn show(&self) {
        match self {
            State::Climbing(ref data) => data.show(),
            State::Driving(ref data) => data.show(),
        }
    }

    fn add(&mut self){
        match self {
            State::Climbing(ref mut data) => data.add(),
            State::Driving(ref mut data) => data.add(),
        }
    }
}

fn main() {

    let mut v = Vec::new();

    v.push(State::Climbing(Data{x: 10 , sta : ClimbingState::Up}));
    v.push(State::Driving(Data{x: 16 , sta : DrivingState::Stop}));

     for mut p in v {
         p.add();
         p.show();
     }
}

I really don’t know if what I did is good or not. I have the feeling that i miss something or I don’t fully understand the rust logic.

I tried to write a function which returns the Date struct from the State enum.

I open to your suggestions!