use super::ClipId;
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct SubClipId(Uuid);
impl SubClipId {
#[must_use]
pub fn new() -> Self {
Self(Uuid::new_v4())
}
#[must_use]
pub const fn from_uuid(uuid: Uuid) -> Self {
Self(uuid)
}
#[must_use]
pub const fn as_uuid(&self) -> &Uuid {
&self.0
}
}
impl Default for SubClipId {
fn default() -> Self {
Self::new()
}
}
impl std::fmt::Display for SubClipId {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SubClip {
pub id: SubClipId,
pub parent_clip_id: ClipId,
pub name: String,
pub in_point: i64,
pub out_point: i64,
pub description: Option<String>,
}
impl SubClip {
#[must_use]
pub fn new(
parent_clip_id: ClipId,
name: impl Into<String>,
in_point: i64,
out_point: i64,
) -> Self {
Self {
id: SubClipId::new(),
parent_clip_id,
name: name.into(),
in_point,
out_point,
description: None,
}
}
#[must_use]
pub const fn duration(&self) -> i64 {
self.out_point - self.in_point
}
#[must_use]
pub const fn is_valid(&self) -> bool {
self.in_point < self.out_point
}
pub fn set_description(&mut self, description: impl Into<String>) {
self.description = Some(description.into());
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_subclip_creation() {
let parent_id = ClipId::new();
let subclip = SubClip::new(parent_id, "Action Scene", 100, 500);
assert_eq!(subclip.name, "Action Scene");
assert_eq!(subclip.in_point, 100);
assert_eq!(subclip.out_point, 500);
assert_eq!(subclip.duration(), 400);
assert!(subclip.is_valid());
}
#[test]
fn test_invalid_subclip() {
let parent_id = ClipId::new();
let subclip = SubClip::new(parent_id, "Invalid", 500, 100);
assert!(!subclip.is_valid());
}
}