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 ...
[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 .
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!