1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
// Copyright 2020 Jared Forth.
//
// Licensed under the GNU General Public License v3.0 <LICENSE or
// https://www.gnu.org/licenses/gpl-3.0.en.html>.
// This file may not be copied, modified, or distributed
// except according to those terms.

//! Utilities for common filesystem operations.
//!
//! **lilypond** provides an API to ergonomically wrap LilyPond,
//! and provide Rust types that resolve to LilyPond output.

use std::process::Command;
use std::io::{self, Write};
use std::path::Path;

/// Compiles a `.ly` source file
///
/// # Usage
///
/// ```
/// use lilypond::compile;
///
/// let input = "test.ly";
/// let output = "test.pdf";
/// // Create test input file
/// fsutils::write_file(input, "{ c e g }");
///
/// if compile(input) {
///    // LilyPond is probably installed
///    assert_eq!(fsutils::path_exists(output), true);
/// } else {
///     // LilyPond is not installed and we will
///     // not get an output
///     assert_eq!(fsutils::path_exists(output), false);
/// }
///
/// // Cleanup
/// fsutils::rm(input);
/// fsutils::rm(output);
///
/// ```
pub fn compile(input_file: &'static str) -> bool {
    if is_lilypond_file(input_file) {
        match Command::new("lilypond")
            .arg(input_file)
            .output() {
            Ok(o) => {
                if o.status.success() {
                    println!("Compiled {}", input_file);
                    io::stdout().write_all(o.stdout.as_ref()).unwrap();
                    true
                } else {
                    io::stdout().write_all(o.stderr.as_ref()).unwrap();
                    false
                }
            }
            Err(e) => {
                println!("Could not run LilyPond. Error: {}", e);
                println!("Install LilyPond at https://lilypond.org/download.html");
                false
            }
        }
    } else {
        println!("File {} does not exist or is invalid.", input_file);
        println!("Make sure your file has the .ly extension");
        false
    }
}

/// Checks if file has `.ly` extension
///
/// # Usage:
///
/// ```
/// use lilypond::is_lilypond_file;
///
/// let valid = "test.ly";
/// let invalid = "test.png";
/// // Create valid file
/// fsutils::create_file(valid);
/// // Create invalid file
/// fsutils::create_file(invalid);
///
/// assert_eq!(is_lilypond_file(valid), true);
/// assert_eq!(is_lilypond_file(invalid), false);
/// // Will also return false if file does not exist
/// assert_eq!(is_lilypond_file("does_not_exit.txt"), false);
///
/// // Clean up
/// fsutils::rm(valid);
/// fsutils::rm(invalid);
/// ```
pub fn is_lilypond_file(filename: &'static str) -> bool {
    match Path::new(filename).extension() {
        Some(ex) =>  {
            if ex == "ly" {
                true
            } else {
                false
            }
        }
        None => false
    }
}