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}