diff/diff.rs
1//! Example of the `p4 diff` command using the builder pattern.
2//!
3//! `p4 diff` has three mutually exclusive modes, tracked at compile time by
4//! the command's type parameter:
5//!
6//! - [`Diff<Unselected>`]: no mode selected yet — enter workspace mode with
7//! [`Diff::force`], [`Diff::differing_only`], or [`Diff::diff_nontext`], or
8//! stream-spec mode with [`Diff::stream_spec_mode`].
9//! - [`Diff<WorkspaceMode<M>>`]: diff workspace files against the depot. The
10//! inner `M` parameter isolates `-m max` ([`WorkspaceRegularMode`]) from
11//! `-soptions` ([`WorkspaceDisplayMode`]).
12//! - [`Diff<StreamSpecMode>`]: diff stream specs via `-As`.
13//!
14//! Run with:
15//!
16//! ```text
17//! cargo run --example diff
18//! ```
19
20use std::ffi::OsStr;
21
22use perforce_cli::P4Cli;
23use perforce_cli::cmd::DiffOptionsBuilder;
24use perforce_cli::cmd::diff::DisplayOptions;
25use perforce_cli::spawn::{ParameterizedOutput, ParameterizedSpawn};
26
27fn main() -> std::io::Result<()> {
28 let p4 = P4Cli::default();
29
30 // Workspace mode: force a diff against head, use the unified format with
31 // whitespace-insensitive comparison, and limit output to the first 10
32 // files. `force(true)` transitions the command into `WorkspaceMode`, and
33 // `limit(10)` further transitions it into `WorkspaceRegularMode` (where
34 // `-soptions` is unavailable).
35 let mut diff = p4
36 .diff()
37 .force(true)
38 .diff_options(DiffOptionsBuilder::unified(None).ignore_all_whitespace())
39 .limit(10);
40
41 let files = [OsStr::new("//depot/project/src/...")];
42 let output = diff.output_with(&files)?;
43 println!("{}", String::from_utf8_lossy(&output.stdout));
44
45 // Display mode: instead of full diffs, list only the unopened files that
46 // differ from the depot. `display_options` transitions `WorkspaceMode`
47 // into `WorkspaceDisplayMode`, where `-m max` is unavailable.
48 let mut list_changed = p4
49 .diff()
50 .force(true)
51 .display_options(DisplayOptions::UnopenedChanged);
52
53 let output = list_changed.output_with(&files)?;
54 println!("{}", String::from_utf8_lossy(&output.stdout));
55
56 // Stream-spec mode: diff a privately edited stream spec against the head
57 // version of another stream. `stream_spec_mode` transitions the command
58 // into `StreamSpecMode`; the stream spec is passed to `spawn_with`.
59 let mut stream_diff = p4.diff().stream_spec_mode();
60 let mut child = stream_diff.spawn_with(Some("//streams/main@head"))?;
61 child.wait()?;
62
63 Ok(())
64}