Skip to main content

movie_editor/
main.rs

1//! Opens a film (`.ravenmovie`) or a bug report (`.ravenbug`) and edits it. What a
2//! report says shows in the terminal, and saving keeps the film beside it.
3
4use std::path::PathBuf;
5
6use ravenrs::movie::{BugReport, EditorLabels, EditorState, Movie, MovieEditor, MovieLabels};
7use ravenrs::native::{OpenDialog, PlatformError, WindowOptions, run};
8use ravenrs::prelude::*;
9
10/// The film in a file, whichever kind of file it is.
11fn film_in(bytes: &[u8]) -> Result<Movie, String> {
12    if let Ok(report) = BugReport::from_bytes(bytes) {
13        println!("{}: {}", report.kind, report.description);
14        for (name, value) in &report.details {
15            println!("{name}: {value}");
16        }
17        if let Some(area) = report.area {
18            println!("marked: {}x{} at {}, {}", area.width, area.height, area.x, area.y);
19        }
20        for element in &report.elements {
21            println!("under the box: {element}");
22        }
23        for error in &report.errors {
24            println!("error: {error}");
25        }
26        return report.film.ok_or_else(|| "This report came without a film.".to_owned());
27    }
28    Movie::from_bytes(bytes).map_err(|e| e.to_string())
29}
30
31fn main() -> Result<(), PlatformError> {
32    let chosen = std::env::args().nth(1).map(PathBuf::from).or_else(|| {
33        OpenDialog::new().title("Open a film").filter("Film or bug report", &["ravenmovie", "ravenbug"]).ask()
34    });
35    let Some(path) = chosen else {
36        return Ok(());
37    };
38    let film = match std::fs::read(&path).map_err(|e| e.to_string()).and_then(|bytes| film_in(&bytes)) {
39        Ok(film) => film,
40        Err(why) => {
41            eprintln!("{}: {why}", path.display());
42            std::process::exit(1);
43        }
44    };
45    let target = path.with_extension("ravenmovie");
46    let editor = MovieEditor::new(EditorState::new(film))
47        .labels(EditorLabels::pt_br())
48        .player_labels(MovieLabels::pt_br())
49        .on_save(move |film: &Movie| {
50            if let Err(e) = std::fs::write(&target, film.to_bytes()) {
51                eprintln!("{}: {e}", target.display());
52            }
53        });
54    run(editor, WindowOptions::new("Editor de filmes").size(1400.0, 900.0).theme(Theme::raven_dark()))
55}
56
57#[cfg(test)]
58mod tests {
59    use super::*;
60
61    #[test]
62    fn a_report_without_a_film_says_so_and_rubbish_is_refused() {
63        let report = BugReport { description: "x".to_owned(), ..BugReport::default() };
64        assert!(film_in(&report.to_bytes()).is_err());
65        assert!(film_in(b"nope").is_err());
66    }
67}