SPIKE: Flip TraxRecord/Activity relationship #180

Closed
opened 2024-02-07 14:57:22 +00:00 by savanni · 1 comment
Owner

Currently the TraxRecord/Activity relationship looks like this:

enum TraxRecord {
    Weight(Weight),
    BikeRide(TimeDistance),
    Run(TimeDistance),
}

When I want to update a bike ride, I've written a function like this:

fn update_time_distance(record: Record<TimeDistance>) {
    let existing = /* get the RecordState<Record<TraxRecord>> based on record.id */
    let updated_record = match *existing {
        BikeRide(_) => Record{ id: record.id, data: BikeRide(record.data) },
        Run(_) => Record{ id: record.id, data: Run(record.data) },
        ...
    }
}

I'm having to write a lot of obtuse code to deal with the wrapping and unwrapping of data when I know for sure that I want to be working with TimeDistanceRecord data.

I know that I wrote this structure with the idea that filtering to particular activity types should be easier than it was with the legacy data structure, but that seems to have come at the cost of making it very difficult to manipulate the records in a type-safe way.

In a spike, I invert all of the code back to the legacy format, so that the structure of the activity is primary, and the actual activity is an attribute:

enum TraxRecord {
    Weight(Weight),
    TimeDistance(TimeDistance)
}

enum TimeDistanceWorkoutType {
    BikeRide,
    Run,
}

struct TimeDistance {
    activity: TimeDistanceWorkoutType
    timestamp: chrono::NaiveDateTime,
    duration: si::Second<f64>,
    /* etc */
}

Compare the resulting data manipulation code to the current code to determine which is easier to work with.

Currently the TraxRecord/Activity relationship looks like this: ```rust enum TraxRecord { Weight(Weight), BikeRide(TimeDistance), Run(TimeDistance), } ``` When I want to update a bike ride, I've written a function like this: ```rust fn update_time_distance(record: Record<TimeDistance>) { let existing = /* get the RecordState<Record<TraxRecord>> based on record.id */ let updated_record = match *existing { BikeRide(_) => Record{ id: record.id, data: BikeRide(record.data) }, Run(_) => Record{ id: record.id, data: Run(record.data) }, ... } } ``` I'm having to write a lot of obtuse code to deal with the wrapping and unwrapping of data when I know for sure that I want to be working with TimeDistanceRecord data. I know that I wrote this structure with the idea that filtering to particular activity types should be easier than it was with the legacy data structure, but that seems to have come at the cost of making it very difficult to manipulate the records in a type-safe way. In a spike, I invert all of the code back to the legacy format, so that the structure of the activity is primary, and the actual activity is an attribute: ```rust enum TraxRecord { Weight(Weight), TimeDistance(TimeDistance) } enum TimeDistanceWorkoutType { BikeRide, Run, } struct TimeDistance { activity: TimeDistanceWorkoutType timestamp: chrono::NaiveDateTime, duration: si::Second<f64>, /* etc */ } ``` Compare the resulting data manipulation code to the current code to determine which is easier to work with.
savanni added this to the Fitnesstrax project 2024-02-07 14:57:22 +00:00
savanni added this to the Fitnesstrax: MVP Basic editing milestone 2024-02-07 15:09:41 +00:00
Author
Owner

I finished this in #182 - Invert the TraxRecord - monorepo - gitea: Gitea Service. It did not immediately give the benefits I was hoping for, but I got the hoped-for benefits as I was finished #169 - Render and be able to edit bike rides (and sorta other time distance workouts) - monorepo - gitea: Gitea Service.

I finished this in [#182 - Invert the TraxRecord - monorepo - gitea: Gitea Service](https://git.luminescent-dreams.com/savanni/monorepo/pulls/182). It did not immediately give the benefits I was hoping for, but I got the hoped-for benefits as I was finished [#169 - Render and be able to edit bike rides (and sorta other time distance workouts) - monorepo - gitea: Gitea Service](https://git.luminescent-dreams.com/savanni/monorepo/pulls/169).
Sign in to join this conversation.
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: savanni/monorepo#180
No description provided.