pub fn advance(&mut self, direction: Direction) -> Option<ModelType> {
        let target_timestamp = match direction {
            Direction::Forward => self.target_timestamp + Duration::from_secs(1),
            Direction::Reverse => self.target_timestamp - Duration::from_secs(1),
        };

        let (next_timestamp, next_sample) =
            self.store
                .extract_sample_and_log(target_timestamp, direction, &self.logger)?;

        // If we detect a direction change, no need to generate a model, we can
        // just save and move to the next round.
        if direction != self.current_direction {
            self.current_direction = direction;
            self.cached_sample = Some(next_sample);
            self.target_timestamp = next_timestamp;

            return self.advance(direction);
        }

        match direction {
            Direction::Forward => {
                let sample_package = SamplePackage::<FrameType>::new(
                    self.cached_sample.take(),
                    self.target_timestamp,
                    next_sample,
                    next_timestamp,
                );
                let model = self.store.to_model(&sample_package);
                self.cached_sample = Some(sample_package.newer_sample);
                self.target_timestamp = next_timestamp;
                model
            }
            Direction::Reverse => {
                let sample_package = SamplePackage::<FrameType>::new(
                    Some(next_sample),
                    next_timestamp,
                    self.cached_sample.take().expect(
                        "No cached sample avaialbe, the Advance module may not be initialized",
                    ),
                    self.target_timestamp,
                );
                let model = self.store.to_model(&sample_package);
                self.cached_sample = sample_package.older_sample;
                self.target_timestamp = next_timestamp;
                model
            }
        }
    }
/// Generate the next Model base on the moving direction.
//
// For all of the comment below, we will use the following example samples:
// [1, 2, 4, 8, 16, 32, 64]
//
// Object Saving base on direction:
// * tl;dr: We always save the newly generated sample regardless of the direction.
//
// * Forward: We always save the newer sample and its timestamp.
//            While we are displaying {8}, we will also need {4} to generate
//            a model. The moving direction is forward, so we will save {8}.
//            When next move forward command comes, we will display {16}. So
//            that we can use the saved {8} to generate a new model. And the
//            {16} will be saved after generate the model.
//
// * Reverse: We always save the older sample and its timestamp.
//            While we are displaying {8}, we will also need {4} to generate
//            a model. The moving direction is reverse, so we will save {4}.
//            When next move reverse command comes, we will display {4}. In
//            that case, we can just query {2} to generate a new model. And
//            the {2} will be saved after generate the model.
//
// Corner cases:
// * When direction changes, we will advance two times in the changing direction.
//   Let's say the current direction is forward, and we are displaying {8}. So
//   the current cached_sample is {8}. We received a command to move reverse.
//   So that we are expected to display {4}, which will require sample {2}. When
//   the first time we call advance(Reverse), we are still displaying {8}, but
//   the cached_sample becomes {4}. We call advance(Reverse) again, we are will
//   display {4} and saved {2}, which is what we expected.
//
// * When reach either end, we don't move forward. Return None in other words,
//   and save nothing.
//
// * When direction change meet reach the end. We don't need any speical handling
//   Let's say we are displaying {2} and current direction is forward. We get
//   a command to move reverse, so we will call advance(reverse) twice. The
//   first time, we are displaying {2} and save {1}. And the second will return
//   None. So we changed the direction, but didn't change the display since we
//   already reached the end.
Generate the next Model base on the moving direction.
For all of the comment below, we will use the following example samples:
[1, 2, 4, 8, 16, 32, 64]

Object Saving base on direction:
tl;dr: We always save the newly generated sample regardless of the direction.

We always save the newer sample and its timestamp.
While we are displaying {8}, we will also need {4} to generate
a model. The moving direction is forward, so we will save {8}.
When next move forward command comes, we will display {16}. So
that we can use the saved {8} to generate a new model. And the
{16} will be saved after generate the model.

We always save the older sample and its timestamp.
While we are displaying {8}, we will also need {4} to generate
a model. The moving direction is reverse, so we will save {4}.
When next move reverse command comes, we will display {4}. In
that case, we can just query {2} to generate a new model. And
the {2} will be saved after generate the model.

Corner cases:
When direction changes, we will advance two times in the changing direction.
Let's say the current direction is forward, and we are displaying {8}. So
the current cached_sample is {8}. We received a command to move reverse.
So that we are expected to display {4}, which will require sample {2}. When
the first time we call advance(Reverse), we are still displaying {8}, but
the cached_sample becomes {4}. We call advance(Reverse) again, we are will
display {4} and saved {2}, which is what we expected.

When reach either end, we don't move forward. Return None in other words,
and save nothing.

When direction change meet reach the end. We don't need any speical handling
Let's say we are displaying {2} and current direction is forward. We get
a command to move reverse, so we will call advance(reverse) twice. The
first time, we are displaying {2} and save {1}. And the second will return
None. So we changed the direction, but didn't change the display since we
already reached the end.
Generate the next Model base on the moving direction . For all of the comment below we will use the following example samples : [ 1 2 4 8 16 32 64 ] Object Saving base on direction : tl ; dr : We always save the newly generated sample regardless of the direction . We always save the newer sample and its timestamp . While we are displaying { 8 } we will also need { 4 } to generate a model . The moving direction is forward so we will save { 8 } . When next move forward command comes we will display { 16 } . So that we can use the saved { 8 } to generate a new model . And the { 16 } will be saved after generate the model . We always save the older sample and its timestamp . While we are displaying { 8 } we will also need { 4 } to generate a model . The moving direction is reverse so we will save { 4 } . When next move reverse command comes we will display { 4 } . In that case we can just query { 2 } to generate a new model . And the { 2 } will be saved after generate the model . Corner cases : When direction changes we will advance two times in the changing direction . Let ' s say the current direction is forward and we are displaying { 8 } . So the current cached_sample is { 8 } . We received a command to move reverse . So that we are expected to display { 4 } which will require sample { 2 } . When the first time we call advance ( Reverse ) we are still displaying { 8 } but the cached_sample becomes { 4 } . We call advance ( Reverse ) again we are will display { 4 } and saved { 2 } which is what we expected . When reach either end we don ' t move forward . Return None in other words and save nothing . When direction change meet reach the end . We don ' t need any speical handling Let ' s say we are displaying { 2 } and current direction is forward . We get a command to move reverse so we will call advance ( reverse ) twice . The first time we are displaying { 2 } and save { 1 } . And the second will return None . So we changed the direction but didn ' t change the display since we already reached the end .
pub fn advance(&mut self, direction: Direction) -> Option<ModelType> {
        let target_timestamp = match direction {
            Direction::Forward => self.target_timestamp + Duration::from_secs(1),
            Direction::Reverse => self.target_timestamp - Duration::from_secs(1),
        };
        let (next_timestamp, next_sample) =
            self.store
                .extract_sample_and_log(target_timestamp, direction, &self.logger)?;
        // If we detect a direction change, no need to generate a model, we can
        // just save and move to the next round.
        if direction != self.current_direction {
            self.current_direction = direction;
            self.cached_sample = Some(next_sample);
            self.target_timestamp = next_timestamp;
            return self.advance(direction);
        }
        match direction {
            Direction::Forward => {
                let sample_package = SamplePackage::<FrameType>::new(
                    self.cached_sample.take(),
                    self.target_timestamp,
                    next_sample,
                    next_timestamp,
                );
                let model = self.store.to_model(&sample_package);
                self.cached_sample = Some(sample_package.newer_sample);
                self.target_timestamp = next_timestamp;
                model
            }
            Direction::Reverse => {
                let sample_package = SamplePackage::<FrameType>::new(
                    Some(next_sample),
                    next_timestamp,
                    self.cached_sample.take().expect(
                        "No cached sample avaialbe, the Advance module may not be initialized",
                    ),
                    self.target_timestamp,
                );
                let model = self.store.to_model(&sample_package);
                self.cached_sample = sample_package.older_sample;
                self.target_timestamp = next_timestamp;
                model
            }
        }
    }
pub fn advance ( & mut self , direction : Direction ) -> Option < ModelType > { let target_timestamp = match direction { Direction :: Forward => self . target_timestamp + Duration :: from_secs ( 1 ) , Direction :: Reverse => self . target_timestamp - Duration :: from_secs ( 1 ) , } ; let ( next_timestamp , next_sample ) = self . store . extract_sample_and_log ( target_timestamp , direction , & self . logger ) ? ; // If we detect a direction change, no need to generate a model, we can // just save and move to the next round. if direction != self . current_direction { self . current_direction = direction ; self . cached_sample = Some ( next_sample ) ; self . target_timestamp = next_timestamp ; return self . advance ( direction ) ; } match direction { Direction :: Forward => { let sample_package = SamplePackage :: < FrameType > :: new ( self . cached_sample . take ( ) , self . target_timestamp , next_sample , next_timestamp , ) ; let model = self . store . to_model ( & sample_package ) ; self . cached_sample = Some ( sample_package . newer_sample ) ; self . target_timestamp = next_timestamp ; model } Direction :: Reverse => { let sample_package = SamplePackage :: < FrameType > :: new ( Some ( next_sample ) , next_timestamp , self . cached_sample . take ( ) . expect ( " " , ) , self . target_timestamp , ) ; let model = self . store . to_model ( & sample_package ) ; self . cached_sample = sample_package . older_sample ; self . target_timestamp = next_timestamp ; model } } }
Generate the next Model base on the moving direction.
Generate the next Model base on the moving direction .
&mut self
direction
Direction
&mut self
direction
Direction