ensuring that slides can be created by different things

This commit is contained in:
Chris Cochrun 2024-10-08 06:18:26 -05:00
parent 887fc733e7
commit 8f065380aa
7 changed files with 270 additions and 50 deletions

View file

@ -1,6 +1,7 @@
use std::path::PathBuf;
use std::{error::Error, fmt::Display, path::PathBuf};
use color_eyre::eyre::Result;
use color_eyre::eyre::{eyre, Result};
use tracing::debug;
use crate::{
images::Image, kinds::ServiceItemKind,
@ -21,19 +22,81 @@ pub enum TextAlignment {
BottomRight,
}
#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct Background {
path: PathBuf,
kind: BackgroundKind,
}
impl TryFrom<String> for Background {
type Error = ParseError;
fn try_from(value: String) -> Result<Self, Self::Error> {
let extension = value.rsplit_once('.').unwrap_or_default();
match extension.0 {
"jpg" | "png" | "webp" => Ok(Self {
path: PathBuf::from(value),
kind: BackgroundKind::Image,
}),
"mp4" | "mkv" | "webm" => Ok(Self {
path: PathBuf::from(value),
kind: BackgroundKind::Video,
}),
_ => Err(ParseError::NonBackgroundFile)
}
}
}
impl TryFrom<PathBuf> for Background {
type Error = ParseError;
fn try_from(value: PathBuf) -> Result<Self, Self::Error> {
let extension = value.extension().unwrap_or_default().to_str().unwrap_or_default();
match extension {
"jpg" | "png" | "webp" => Ok(Self {
path: value,
kind: BackgroundKind::Image,
}),
"mp4" | "mkv" | "webm" => Ok(Self {
path: value,
kind: BackgroundKind::Video,
}),
_ => Err(ParseError::NonBackgroundFile)
}
}
}
#[derive(Debug)]
pub enum ParseError {
NonBackgroundFile,
}
impl Error for ParseError {}
impl Display for ParseError {
fn fmt(
&self,
f: &mut std::fmt::Formatter<'_>,
) -> std::fmt::Result {
let message = match self {
Self::NonBackgroundFile => "The file is not a recognized image or video type",
};
write!(f, "Error: {message}")
}
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub enum Background {
pub enum BackgroundKind {
#[default]
Image,
Video,
}
impl From<String> for Background {
impl From<String> for BackgroundKind {
fn from(value: String) -> Self {
if value == "image" {
Background::Image
BackgroundKind::Image
} else {
Background::Video
BackgroundKind::Video
}
}
}
@ -42,7 +105,7 @@ impl From<String> for Background {
struct Slide {
id: i32,
database_id: i32,
background: PathBuf,
background: Background,
text: String,
font: String,
font_size: i32,
@ -75,9 +138,13 @@ impl From<Song> for Slide {
}
impl From<Video> for Slide {
fn from(_video: Video) -> Self {
fn from(video: Video) -> Self {
Self {
kind: ServiceItemKind::Video,
background: Background::try_from(video.path).unwrap_or_default(),
video_loop: video.looping,
video_start_time: video.start_time.unwrap_or_default(),
video_end_time: video.end_time.unwrap_or_default(),
..Default::default()
}
}
@ -103,34 +170,158 @@ impl From<Presentation> for Slide {
}
impl SlideModel {
pub fn add_song_to_end(&mut self, song: Song) -> Result<()> {
pub fn add_song(&mut self, song: Song, index: i32) -> Result<()> {
let lyrics = song.get_lyrics()?;
let mut slides: Vec<Slide> = lyrics
let current_length = self.slides.len();
let slides: Vec<Slide> = lyrics
.iter()
.map(|lyric| Slide {
background: song.background.clone(),
background: song.background.clone().unwrap_or_default(),
text: lyric.to_owned(),
font: song.font.clone(),
font_size: song.font_size,
font: song.font.clone().unwrap_or_default(),
font_size: song.font_size.unwrap_or_default(),
kind: ServiceItemKind::Song,
text_alignment: song.text_alignment,
text_alignment: song.text_alignment.unwrap_or_default(),
..Default::default()
})
.collect();
self.slides.append(&mut slides);
for (location, slide) in slides.iter().enumerate() {
self.slides.insert(location + index as usize, slide.clone());
debug!("Here is the current slide_model: {:?}", self);
}
if self.slides.len() > current_length {
Ok(())
} else {
Err(eyre!("The size of the slides vector didn't change"))
}
}
pub fn get_slide(&self, index: i32) -> Option<&Slide> {
self.slides.get(index as usize)
}
pub fn add_video(&mut self, video: Video, index: i32) -> Result<()> {
self.slides.insert(index as usize, Slide::from(video));
Ok(())
}
pub fn add_video_to_end(&mut self, video: Video) -> Result<()> {
self.slides.push(Slide::from(video));
pub fn add_image(&mut self, image: Image, index: i32) -> Result<()> {
self.slides.insert(index as usize, Slide::from(image));
Ok(())
}
pub fn add_presentation(&mut self, presentation: Presentation, index: i32) -> Result<()> {
self.slides.insert(index as usize, Slide::from(presentation));
Ok(())
}
}
#[cfg(test)]
mod test {
use crate::songs::Song;
use pretty_assertions::{assert_eq, assert_ne};
use super::*;
fn test_song() -> Song {
Song {
title: "From The Day".to_string(),
lyrics: Some("Verse 1
When You found me,
I was so blind
My sin was before me,
I was swallowed by pride
Chorus 1
But out of the darkness,
You brought me to Your light
You showed me new mercy
And opened up my eyes
Chorus 2
From the day
You saved my soul
'Til the very moment
When I come home
I'll sing, I'll dance,
My heart will overflow
From the day
You saved my soul
Verse 2
Where brilliant light
Is all around
And endless joy
Is the only sound
Chorus 3
Oh, rest my heart
Forever now
Oh, in Your arms
I'll always be found
Bridge 1
My love is Yours
My heart is Yours
My life is Yours
Forever
My love is Yours
My heart is Yours
My life is Yours
Forever
Other 1
From the Day
I Am They
Other 2
Ending 1
Oh Oh Oh
From the day
You saved my soul".to_string()),
verse_order: Some("O1 V1 C1 C2 O2 V2 C3 C2 O2 B1 C2 C2 E1 O2"
.to_string()
.split(' ')
.map(|s| s.to_string())
.collect()),
..Default::default()
}
}
fn test_song_verse_one() -> String {
"When You found me,\nI was so blind\nMy sin was before me,\nI was swallowed by pride".to_string()
}
fn test_song_last_verse() -> String {
"Oh Oh Oh\nFrom the day\nYou saved my soul\n".to_string()
}
#[test]
pub fn test_slides() {
assert_eq!(true, true)
pub fn test_add_song_to_slides() {
let song = test_song();
let mut slide_model = SlideModel::default();
let result = slide_model.add_song(song, 0);
match result {
Ok(_) => {
let slide = slide_model.get_slide(15).unwrap();
let new_slide = Slide {
text: test_song_last_verse(),
..Default::default()
};
assert_eq!(slide, &new_slide);
let slide = slide_model.get_slide(1).unwrap();
let new_slide = Slide {
text: test_song_verse_one(),
..Default::default()
};
assert_eq!(slide, &new_slide);
},
Err(e) => {
panic!("There was a problem adding the slide: {:?}", e);
}
}
}
}