window_enumerator_formatter/
lib.rs

1//! A powerful formatting library for window information with multiple output formats and templates.
2//!
3//! This crate provides flexible formatting capabilities for window information,
4//! supporting various output formats and customizable templates.
5//!
6//! # Features
7//!
8//! - **Multiple Formats**: JSON, YAML, CSV, Table, Simple, and Detailed formats
9//! - **Template System**: Field selection, key-value pairs, and custom templates
10//! - **Highly Configurable**: Title truncation, header control, and output customization
11//! - **Easy to Use**: Simple API with rich examples and builder pattern
12//! - **Flexible**: Works standalone or with `window-enumerator` integration
13//! - **Optional Dependencies**: Minimal required dependencies
14//!
15//! # Quick Start
16//!
17//! ## Standalone Usage
18//!
19//! ```
20//! use window_enumerator_formatter::{
21//!     WindowInfo, WindowPosition, OutputFormat, WindowListFormat
22//! };
23//! use std::path::PathBuf;
24//!
25//! // Create window data using builder pattern
26//! let window = WindowInfo::builder()
27//!     .hwnd(12345)
28//!     .pid(1234)
29//!     .title("Test Window".to_string())
30//!     .class_name("TestClass".to_string())
31//!     .process_name("test.exe".to_string())
32//!     .process_file(PathBuf::from("test.exe"))
33//!     .index(1)
34//!     .position(WindowPosition::default())
35//!     .build();
36//!
37//! let windows = vec![window];
38//!
39//! // Format with different output formats
40//! println!("JSON: {}", windows.format_with(OutputFormat::Json));
41//! println!("Table: {}", windows.format_with(OutputFormat::Table));
42//! println!("CSV: {}", windows.format_with(OutputFormat::Csv));
43//!
44//! // Individual window formatting
45//! println!("Single window: {}", windows[0].format_with(OutputFormat::Simple));
46//! ```
47//!
48//! ## Using different output formats:
49//! ```
50//! use window_enumerator_formatter::{
51//!     WindowInfo, WindowPosition, OutputFormat, WindowListFormat, FormatConfig
52//! };
53//! use std::path::PathBuf;
54//!
55//! let windows = vec![
56//!     WindowInfo::builder()
57//!         .hwnd(12345)
58//!         .pid(1234)
59//!         .title("Browser".to_string())
60//!         .class_name("Chrome_WidgetWin_1".to_string())
61//!         .process_name("chrome.exe".to_string())
62//!         .process_file(PathBuf::from("C:\\Program Files\\Google\\Chrome\\chrome.exe"))
63//!         .index(1)
64//!         .position(WindowPosition { x: 100, y: 100, width: 1920, height: 1080 })
65//!         .build(),
66//!     WindowInfo::builder()
67//!         .hwnd(67890)
68//!         .pid(5678)
69//!         .title("Text Editor".to_string())
70//!         .class_name("Notepad".to_string())
71//!         .process_name("notepad.exe".to_string())
72//!         .process_file(PathBuf::from("C:\\Windows\\notepad.exe"))
73//!         .index(2)
74//!         .position(WindowPosition { x: 50, y: 50, width: 800, height: 600 })
75//!         .build(),
76//! ];
77//!
78//! // JSON format
79//! println!("JSON:\n{}", windows.format_with(OutputFormat::Json));
80//!
81//! // Table format
82//! println!("\nTable:\n{}", windows.format_with(OutputFormat::Table));
83//!
84//! // CSV format
85//! println!("\nCSV:\n{}", windows.format_with(OutputFormat::Csv));
86//!
87//! // Simple format
88//! println!("\nSimple:\n{}", windows.format_with(OutputFormat::Simple));
89//! ```
90//!
91//! ## Using custom templates:
92//! ```
93//! use window_enumerator_formatter::{
94//!     WindowInfo, WindowPosition, OutputFormat, TemplateFormat, FormatConfig
95//! };
96//! use std::path::PathBuf;
97//!
98//! let window = WindowInfo::builder()
99//!     .hwnd(12345)
100//!     .pid(1234)
101//!     .title("My Application".to_string())
102//!     .class_name("MyAppClass".to_string())
103//!     .process_name("myapp.exe".to_string())
104//!     .process_file(PathBuf::from("myapp.exe"))
105//!     .index(1)
106//!     .position(WindowPosition { x: 100, y: 200, width: 1024, height: 768 })
107//!     .build();
108//!
109//! // Field values only template
110//! let config = FormatConfig {
111//!     format: OutputFormat::Custom,
112//!     template: Some(TemplateFormat::Fields(vec![
113//!         "index".into(),
114//!         "pid".into(),
115//!         "title".into()
116//!     ])),
117//!     ..Default::default()
118//! };
119//! println!("Fields: {}", window.format(&config));
120//!
121//! // Key-value template
122//! let config = FormatConfig {
123//!     format: OutputFormat::Custom,
124//!     template: Some(TemplateFormat::KeyValue(vec![
125//!         "index".into(),
126//!         "hwnd".into(),
127//!         "title".into()
128//!     ])),
129//!     ..Default::default()
130//! };
131//! println!("Key-Value: {}", window.format(&config));
132//!
133//! // Custom template string
134//! let config = FormatConfig {
135//!     format: OutputFormat::Custom,
136//!     template: Some(TemplateFormat::Custom(
137//!         "Window[{index}] | PID:{pid} | Title:{title}".into()
138//!     )),
139//!     ..Default::default()
140//! };
141//! println!("Custom: {}", window.format(&config));
142//! ```
143//!
144//! ## Advanced configuration:
145//! ```
146//! use window_enumerator_formatter::{
147//!     WindowInfo, WindowPosition, OutputFormat, FormatConfig, WindowListFormat
148//! };
149//! use std::path::PathBuf;
150//!
151//! let windows = vec![
152//!     WindowInfo::builder()
153//!         .hwnd(12345)
154//!         .pid(1234)
155//!         .title("This is a very long window title that might need truncation".to_string())
156//!         .class_name("SomeClass".to_string())
157//!         .process_name("app.exe".to_string())
158//!         .process_file(PathBuf::from("app.exe"))
159//!         .index(1)
160//!         .position(WindowPosition::default())
161//!         .build(),
162//! ];
163//!
164//! let config = FormatConfig {
165//!     format: OutputFormat::Table,
166//!     show_headers: false,
167//!     max_title_length: Some(20),
168//!     ..Default::default()
169//! };
170//!
171//! println!("{}", windows.format_output(&config));
172//! ```
173//!
174//! ## With window-enumerator integration (requires feature):
175//! ```ignore
176//! // This example requires the `window-enumerator` feature
177//! use window_enumerator::WindowEnumerator;
178//! use window_enumerator_formatter::{OutputFormat, WindowListFormat};
179//!
180//! let mut enumerator = WindowEnumerator::new();
181//! enumerator.enumerate_all_windows().unwrap();
182//! let windows: Vec<_> = enumerator.get_windows().iter().map(|w| w.into()).collect();
183//!
184//! // Format as pretty JSON
185//! println!("{}", windows.format_with(OutputFormat::JsonPretty));
186//!
187//! // Format as YAML
188//! println!("{}", windows.format_with(OutputFormat::Yaml));
189//!
190//! // Format as detailed list
191//! println!("{}", windows.format_with(OutputFormat::Detail));
192//! ```
193
194#![warn(missing_docs)]
195
196mod error;
197mod formatter;
198mod models;
199
200pub use error::FormatError;
201pub use formatter::{
202    FormatConfig, OutputFormat, TemplateFormat, WindowFormatter, WindowListFormat,
203};
204pub use models::{WindowInfo, WindowPosition};
205
206// 为 WindowInfo 实现格式化方法,消除循环依赖
207impl WindowInfo {
208    /// Format this window according to the configuration.
209    pub fn format(&self, config: &FormatConfig) -> String {
210        WindowFormatter::format_window(self, config)
211    }
212
213    /// Format this window with a specific output format.
214    pub fn format_with(&self, format: OutputFormat) -> String {
215        let config = FormatConfig {
216            format,
217            ..Default::default()
218        };
219        self.format(&config)
220    }
221}
222
223/// Prelude module for convenient imports.
224pub mod prelude {
225    pub use crate::{
226        FormatConfig, OutputFormat, TemplateFormat, WindowInfo, WindowListFormat, WindowPosition,
227    };
228}