You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This is a different approach from the previous commit. I zoomed out and considered the over all problem space:
## Desires:
- A representation of the command being run should appear in logs, or the error, or both
- Stdout and Stderr from the command should appear in logs, or the error, but NOT both (if it runs).
- Make non-zero status an error
- Allow for debugging a command that was run after execution (i.e. get command program name, arguments, env, cwd and pass them to something like `WhichProblem`)
- Ideally only have to format `Command` once
## Central std structs:
- `Command` holds all state needed to run a process. Must be `mut` to be run. `&mut` references are exclusive and can be tricky to work with. Cannot be cloned.
- `Output` holds stdout, stderr, and status if the command could be executed.
- `std::io::Error` holds failure information if the process could not boot (for example, could not find the executable)
## Consequences
- Command must be represented a minimum of 3 times for logging:
- For logging
- In the io error state
- In the Ok state so it can be converted into an Err on invalid status
- Another time if we need to access it for debugging i.e. WhichProblem
- We need both a Command representation and Output data at the same time
- Generating an `Output` requires a mutable reference to the command.
- We need both a Command representation and std::io::Err at the same time
## Implementation
I realized that I wanted a flow of data
- Command
- Command w/Name
- Command w/Name & Result<Output, std::io::Error>
This gives us a way to build up a canonical representation of the command as a "name". I chose to implement these three states as structs with functions that allow for transition between structs.
I also need to record if the contents are streamed or not. For this I implemented an enum, but users don't need to see it if they only ever call helper methods like: `stream()` or `run-quietly()`.
Once the final state is achieved, it's still not very ergonomic, so converted it into an enum instead that represents the possible states of the system:
- Command ran, status = 0
- NonZero status, stderr is not streamed
- NonZero status, stderr is already streamed
- IO Error
If someone wants to take this and use it, they can. It would be very easy to map non-zero status back to an `Ok` state as they share the same inner struct type.
However that enum cannot be used as an Error as it contains `& mut Command` with a lifetime which makes it not terribly useful.
I provided a default error enum and an easy way to map that status enum into an error via a method. This allows the end user to be able to chain all `cute_cmd` calls and then to `map` or `map_err` if they need more control.
## TODO
Add `which_problem` integration back in. More docs. Get a review.
0 commit comments