use serde::Serialize;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
#[serde(rename_all = "lowercase")]
pub enum ScreenshotType {
Png,
Jpeg,
}
#[derive(Debug, Clone, Copy, PartialEq, Serialize)]
pub struct ScreenshotClip {
pub x: f64,
pub y: f64,
pub width: f64,
pub height: f64,
}
#[derive(Debug, Clone, Default)]
pub struct ScreenshotOptions {
pub screenshot_type: Option<ScreenshotType>,
pub quality: Option<u8>,
pub full_page: Option<bool>,
pub clip: Option<ScreenshotClip>,
pub omit_background: Option<bool>,
pub timeout: Option<f64>,
}
impl ScreenshotOptions {
pub fn builder() -> ScreenshotOptionsBuilder {
ScreenshotOptionsBuilder::default()
}
pub(crate) fn to_json(&self) -> serde_json::Value {
let mut json = serde_json::json!({});
if let Some(screenshot_type) = &self.screenshot_type {
json["type"] = serde_json::to_value(screenshot_type).unwrap();
}
if let Some(quality) = self.quality {
json["quality"] = serde_json::json!(quality);
}
if let Some(full_page) = self.full_page {
json["fullPage"] = serde_json::json!(full_page);
}
if let Some(clip) = &self.clip {
json["clip"] = serde_json::to_value(clip).unwrap();
}
if let Some(omit_background) = self.omit_background {
json["omitBackground"] = serde_json::json!(omit_background);
}
if let Some(timeout) = self.timeout {
json["timeout"] = serde_json::json!(timeout);
} else {
json["timeout"] = serde_json::json!(crate::DEFAULT_TIMEOUT_MS);
}
json
}
}
#[derive(Debug, Clone, Default)]
pub struct ScreenshotOptionsBuilder {
screenshot_type: Option<ScreenshotType>,
quality: Option<u8>,
full_page: Option<bool>,
clip: Option<ScreenshotClip>,
omit_background: Option<bool>,
timeout: Option<f64>,
}
impl ScreenshotOptionsBuilder {
pub fn screenshot_type(mut self, screenshot_type: ScreenshotType) -> Self {
self.screenshot_type = Some(screenshot_type);
self
}
pub fn quality(mut self, quality: u8) -> Self {
self.quality = Some(quality);
self
}
pub fn full_page(mut self, full_page: bool) -> Self {
self.full_page = Some(full_page);
self
}
pub fn clip(mut self, clip: ScreenshotClip) -> Self {
self.clip = Some(clip);
self
}
pub fn omit_background(mut self, omit_background: bool) -> Self {
self.omit_background = Some(omit_background);
self
}
pub fn timeout(mut self, timeout: f64) -> Self {
self.timeout = Some(timeout);
self
}
pub fn build(self) -> ScreenshotOptions {
ScreenshotOptions {
screenshot_type: self.screenshot_type,
quality: self.quality,
full_page: self.full_page,
clip: self.clip,
omit_background: self.omit_background,
timeout: self.timeout,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_screenshot_type_serialization() {
assert_eq!(
serde_json::to_string(&ScreenshotType::Png).unwrap(),
"\"png\""
);
assert_eq!(
serde_json::to_string(&ScreenshotType::Jpeg).unwrap(),
"\"jpeg\""
);
}
#[test]
fn test_builder_jpeg_with_quality() {
let options = ScreenshotOptions::builder()
.screenshot_type(ScreenshotType::Jpeg)
.quality(80)
.build();
let json = options.to_json();
assert_eq!(json["type"], "jpeg");
assert_eq!(json["quality"], 80);
}
#[test]
fn test_builder_full_page() {
let options = ScreenshotOptions::builder().full_page(true).build();
let json = options.to_json();
assert_eq!(json["fullPage"], true);
}
#[test]
fn test_builder_clip() {
let clip = ScreenshotClip {
x: 10.0,
y: 20.0,
width: 300.0,
height: 200.0,
};
let options = ScreenshotOptions::builder().clip(clip).build();
let json = options.to_json();
assert_eq!(json["clip"]["x"], 10.0);
assert_eq!(json["clip"]["y"], 20.0);
assert_eq!(json["clip"]["width"], 300.0);
assert_eq!(json["clip"]["height"], 200.0);
}
#[test]
fn test_builder_omit_background() {
let options = ScreenshotOptions::builder().omit_background(true).build();
let json = options.to_json();
assert_eq!(json["omitBackground"], true);
}
#[test]
fn test_builder_multiple_options() {
let options = ScreenshotOptions::builder()
.screenshot_type(ScreenshotType::Jpeg)
.quality(90)
.full_page(true)
.timeout(5000.0)
.build();
let json = options.to_json();
assert_eq!(json["type"], "jpeg");
assert_eq!(json["quality"], 90);
assert_eq!(json["fullPage"], true);
assert_eq!(json["timeout"], 5000.0);
}
}