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
//! Subplot data files
//!
//! Subplot can embed data files into test suites. This module provides
//! the representation of the files in a way designed to be cheap to clone
//! so that they can be passed around "by value".
use std::path::{Path, PathBuf};
use std::sync::Arc;
use base64::decode;
/// An embedded data file.
///
/// Embedded data files have names and content. The subplot template will generate
/// a `lazy_static` containing all the data files embedded into the suite. Then
/// generated test functions will extract data files
///
/// If you are using them in your test steps you should take them by value:
///
/// ```rust
/// # use subplotlib::prelude::*;
/// # #[derive(Default)]
/// # struct Context {}
/// # impl ContextElement for Context {}
/// #[step]
/// fn step_using_a_file(context: &mut Context, somefile: SubplotDataFile) {
/// // context.stash_file(somefile);
/// }
///
/// # fn main() {}
/// ```
///
/// For the generated test to correctly recognise how to pass a file in, you
/// **must** mark the argument as a file in your binding:
///
/// ```yaml
/// - when: using {somefile} as a input
/// function: step_using_a_file
/// types:
/// somefile: file
/// ```
#[derive(Debug)]
pub struct SubplotDataFile {
name: Arc<Path>,
data: Arc<[u8]>,
}
impl Clone for SubplotDataFile {
fn clone(&self) -> Self {
Self {
name: Arc::clone(&self.name),
data: Arc::clone(&self.data),
}
}
}
impl Default for SubplotDataFile {
fn default() -> Self {
Self {
name: PathBuf::from("").into(),
data: Vec::new().into(),
}
}
}
impl SubplotDataFile {
/// Construct a new data file object
///
/// Typically this will only be called from the generated test suite.
/// The passed in name and data must be base64 encoded strings and each will
/// be interpreted independently. The name will be treated as a [`PathBuf`]
/// and the data will be stored as a slice of bytes.
///
/// Neither will be interpreted as utf8.
///
/// # Panics
///
/// This will panic if the passed in strings are not correctly base64 encoded.
pub fn new(name: &str, data: &str) -> Self {
let name = decode(name).expect("Subplot generated bad base64?");
let name = String::from_utf8_lossy(&name);
let name: PathBuf = name.as_ref().into();
let name = name.into();
let data = decode(data).expect("Subplot generated bad base64?").into();
Self { name, data }
}
/// Retrieve the filename
pub fn name(&self) -> &Path {
&self.name
}
/// Retrieve the data
pub fn data(&self) -> &[u8] {
&self.data
}
}