Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,13 @@ tokio = { version = "1.47", default-features = false, features = [

[features]
tokio = ["dep:tokio"]
utils = []

[dev-dependencies]
roxmltree = "0.20.0"
tokio-test = "0.4.4"
tokio = { version = "1.47", features = ["full"] }
mkv-element = { path = ".", features = ["tokio"] }
mkv-element = { path = ".", features = ["tokio", "utils"] }

[build-dependencies]
roxmltree = "0.20.0"
Expand Down
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,25 @@ assert_eq!(ebml, ebml_read_4);
# })
```

## Features

This crate provides the following optional features:

- **`tokio`**: Enables asynchronous I/O support using Tokio. This adds `async_read_from()`, `async_read_element()`, and `async_write_to()` methods that work with types implementing `tokio::io::AsyncRead` and `tokio::io::AsyncWrite`.

- **`utils`**: Enables utility modules for working with Matroska files, such as the `view` module. The `view` module provides `MatroskaView` and `SegmentView` structs for efficiently parsing MKV file metadata without loading cluster data into memory.

To enable these features, add them to your `Cargo.toml`:

```toml
[dependencies]
mkv-element = { version = "0.2", features = ["tokio", "utils"] }
```

## Important notes
1. if you need to work with actual MKV files, don't read a whole segment into memory at once, read only the parts you need instead. Real world MKV files can be very large.)
```

## Quick Note
1. if you need to work with actual MKV files, don't read a whole segment into memory at once, read only the parts you need instead. Real world MKV files can be very large.
2. According to the Matroska specifications, segments and clusters can have an "unknown" size (all size bytes set to 1). In that case, the segment/cluster extends to the end of the file or until the next segment/cluster. This needs to handle by the user. Trying to read such elements with this library will result in an [`ElementBodySizeUnknown`](crate::Error::ElementBodySizeUnknown) error.
Expand Down
31 changes: 31 additions & 0 deletions src/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,19 @@ pub mod blocking_impl {
Ok(())
}
}

/// Write an element to a writer provided the header.
pub trait WriteElement: Sized + Element {
/// Write an element to a writer.
fn write_element<W: Write>(&self, header: &Header, w: &mut W) -> crate::Result<()> {
header.write_to(w)?;
let mut buf = vec![];
self.encode_body(&mut buf)?;
w.write_all(&buf)?;
Ok(())
}
}
impl<T: Element> WriteElement for T {}
}
/// tokio non-blocking I/O implementations, supporting async reading and writing.
#[cfg(feature = "tokio")]
Expand Down Expand Up @@ -119,6 +132,24 @@ pub mod tokio_impl {
}
}

/// Write an element to a writer provided the header asynchronously.
pub trait AsyncWriteElement: Sized + Element {
/// Write an element to a writer asynchronously.
fn async_write_element<W: tokio::io::AsyncWrite + Unpin>(
&self,
header: &Header,
w: &mut W,
) -> impl std::future::Future<Output = crate::Result<()>> {
async {
header.async_write_to(w).await?;
let mut buf = vec![];
self.encode_body(&mut buf)?;
Ok(w.write_all(&buf).await?)
}
}
}
impl<T: Element> AsyncWriteElement for T {}

impl Header {
/// Read the body of the element from a reader into memory.
pub(crate) async fn read_body_tokio<R: AsyncRead + Unpin>(
Expand Down
4 changes: 4 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ mod supplement; // Supplementary elements in Matroska. Void elements, CRC-32, et
// following modules are public
pub mod io;

#[cfg(feature = "utils")]
#[cfg_attr(docsrs, doc(cfg(feature = "utils")))]
pub mod view;

// Re-export common types
pub use crate::frame::*;
pub use crate::lacer::*;
Expand Down
Loading