Skip to content

Conversation

codecrafter404
Copy link

Problem

The package creation currently only allows for media files to be read from the filesystem.

Solution

The package now exposes a function to create mediafiles from memory: new_from_memory.
To allow imports both from the filesystem and from memory, a new enum was introduced: MediaFile.

Example usage

use genanki_rs::{Package, Deck, Note, Model, Field, Template, MediaFile};

const VALID_MP3: &[u8] =
    b"\xff\xe3\x18\xc4\x00\x00\x00\x03H\x00\x00\x00\x00LAME3.98.2\x00\x00\x00\
    \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
    \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
    \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
const VALID_JPG: &[u8] =
    b"\xff\xd8\xff\xdb\x00C\x00\x03\x02\x02\x02\x02\x02\x03\x02\x02\x02\x03\x03\
    \x03\x03\x04\x06\x04\x04\x04\x04\x04\x08\x06\x06\x05\x06\t\x08\n\n\t\x08\t\
    \t\n\x0c\x0f\x0c\n\x0b\x0e\x0b\t\t\r\x11\r\x0e\x0f\x10\x10\x11\x10\n\x0c\
    \x12\x13\x12\x10\x13\x0f\x10\x10\x10\xff\xc9\x00\x0b\x08\x00\x01\x00\x01\
    \x01\x01\x11\x00\xff\xcc\x00\x06\x00\x10\x10\x05\xff\xda\x00\x08\x01\x01\
    \x00\x00?\x00\xd2\xcf \xff\xd9";

let model = Model::new(
    1607392319,
    "Simple Model",
    vec![
        Field::new("Question"),
        Field::new("Answer"),
        Field::new("MyMedia"),
    ],
    vec![Template::new("Card 1")
        .qfmt("{{Question}}{{Question}}<br>{{MyMedia}}")
        .afmt(r#"{{FrontSide}}<hr id="answer">{{Answer}}"#)],
);

let mut deck = Deck::new(1234, "Example Deck", "Example Deck with media");
deck.add_note(Note::new(model.clone(), vec!["What is the capital of France?", "Paris", "[sound:sound.mp3]"])?);
deck.add_note(Note::new(model.clone(), vec!["What is the capital of France?", "Paris", r#"<img src="image.jpg">"#])?);

let mut package = Package::new_from_memory(vec![deck], vec![MediaFile::new_from_bytes(VALID_MP3, "sound.mp3"), MediaFile::new_from_bytes(VALID_JPG, "image.jpg")])?;
package.write_to_file("output.apkg")?;

Tests

Although I was unable to successfully run all tests locally, I have implemented a test for importing media files from memory that should pass.

outzip.write_all(&read_file_bytes(path)?)?;
outzip.write_all(&match media_file {
MediaFile::Path(path) => read_file_bytes(path)?,
MediaFile::Bytes(bytes, _) => bytes.clone(),

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This clone is probably not required?


/// Create a new `MediaFile` from bytes from memory and a filename
pub fn new_from_bytes(bytes: &[u8], name: &str) -> Self {
Self::Bytes(bytes.to_vec(), name.to_owned())

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be possible not to call to_vec here and just keep a reference to the bytes? Could potentially avoid a chunky memcopy

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants