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
60 changes: 30 additions & 30 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -163,36 +163,36 @@ jobs:
uses: taiki-e/install-action@cargo-machete
- name: Check For Unused Dependencies
run: cargo machete
#semver-compliance:
# runs-on: ubuntu-latest
# needs: [clippy, no-unused-dependencies]
# steps:
# - name: Git checkout
# uses: actions/checkout@v3
# - name: Cache cargo home
# uses: actions/cache@v3
# env:
# cache-name: cache-cargo-home
# with:
# path: |
# ~/.cargo/bin
# ~/.cargo/registry/index
# ~/.cargo/registry/cache
# ~/.cargo/git/db
# key: ${{ runner.os }}-x86_64-unknown-linux-gnu-build-${{ env.cache-name }}-${{ hashFiles('Cargo.lock') }}
# restore-keys: |
# ${{ runner.os }}-x86_64-unknown-linux-gnu-build-${{ env.cache-name }}-
# - name: Install Rust
# uses: dtolnay/rust-toolchain@master
# with:
# toolchain: stable
# - name: Install Semver Checks
# # no default features so that it uses native Rust TLS instead of trying to link with system TLS.
# uses: taiki-e/install-action@main
# with:
# tool: cargo-semver-checks
# - name: Check Semver Compliance
# run: cargo semver-checks check-release
semver-compliance:
runs-on: ubuntu-latest
needs: [clippy, no-unused-dependencies]
steps:
- name: Git checkout
uses: actions/checkout@v3
- name: Cache cargo home
uses: actions/cache@v3
env:
cache-name: cache-cargo-home
with:
path: |
~/.cargo/bin
~/.cargo/registry/index
~/.cargo/registry/cache
~/.cargo/git/db
key: ${{ runner.os }}-x86_64-unknown-linux-gnu-build-${{ env.cache-name }}-${{ hashFiles('Cargo.lock') }}
restore-keys: |
${{ runner.os }}-x86_64-unknown-linux-gnu-build-${{ env.cache-name }}-
- name: Install Rust
uses: dtolnay/rust-toolchain@master
with:
toolchain: stable
- name: Install Semver Checks
# no default features so that it uses native Rust TLS instead of trying to link with system TLS.
uses: taiki-e/install-action@main
with:
tool: cargo-semver-checks
- name: Check Semver Compliance
run: cargo semver-checks check-release
msrv-compliance:
runs-on: ubuntu-latest
needs: [clippy, no-unused-dependencies, find-msrv]
Expand Down
8 changes: 6 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
[package]
name = "spiel"
version = "0.1.0"
version = "0.2.0"
edition = "2021"
authors = [
"Tait Hoyem <tait@tait.tech>",
]
license = "MIT OR Apache-2.0"
description = "A pure-Rust Spiel format parser, client, and proxy implementation."
repository = "https://github.com/TTWNO/spiel"
Expand All @@ -19,6 +22,7 @@ std = ["alloc"]
alloc = ["serde?/alloc", "dep:bytes"]
poll = []
serde = ["serde/derive", "bytes?/serde", "enumflags2?/serde"]
proptests = ["reader", "client"]

[dependencies]
bytes = { version = "1.9.0", default-features = false, optional = true }
Expand Down Expand Up @@ -68,4 +72,4 @@ required-features = ["client"]
[[example]]
name = "test_provider"
path = "./examples/test_provider.rs"
required-features = ["client"]
required-features = ["client", "reader"]
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Note that features with an unmarked checkbox are not yet implemented.
- [X] `alloc`: pulls in the [`bytes`](https://crates.io/crates/bytes), if `serde` is enabled. It exposes new types like [`crate::MessageOwned`] and [`crate::EventOwned`], which are owned versions of [`crate::Message`] and [`crate::Event`].
- [X] `poll`: add wrapper functions that return `Poll::Pending` when there is not enough data in the buffer. This is not for general use, but rather only if you are creating an async integration.
- [X] `serde`: activate [`serde::Serialize`] and [`serde::Deserialize`] on all types.
- [ ] `provider`: activates [`std`] and pulls in the [`zbus`](https://crates.io/crates/zbus) crate. This will provide the `SpeechProvider` struct, which can be used to provide speech over the Spiel protocol via `DBus`.
- [X] `provider`: activates [`std`] and pulls in the [`zbus`](https://crates.io/crates/zbus) crate. This will provide the `SpeechProvider` struct, which can be used to provide speech over the Spiel protocol via `DBus`.

## MSRV

Expand Down
29 changes: 7 additions & 22 deletions examples/provider.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
use std::{
io::{PipeWriter, Write},
os::fd::OwnedFd,
time::Duration,
};
use std::{io::PipeWriter, os::fd::OwnedFd, time::Duration};

use spiel::{write_message, Event, EventType, Message, Voice, VoiceFeatureSet};
use spiel::{Event, EventType, Message, Voice, VoiceFeatureSet, Writer};
use tokio::time::sleep;
use zbus::{connection::Builder, fdo::Error, interface, zvariant::Fd};

Expand Down Expand Up @@ -39,31 +35,20 @@ impl MySpeechProvider {
// etc.
//
// We are just gonna write a simple `Message::Event`
let header = Message::Version("0.01");
let msg = Message::Event(Event {
let msgs = [Message::Event(Event {
typ: EventType::Word,
start: 69,
end: 420,
name: Some("Hello :)"),
});
})];
// buffer has fixed size in this case
let mut buffer: [u8; 1024] = [0; 1024];
let writer: OwnedFd = pipe_fd
.try_into()
.map_err(|_| Error::IOError("Cannot open file descriptor".to_string()))
.expect("Unable to open file descriptor!");
let mut file = PipeWriter::from(writer);
// TODO: implement a more convenient way to not have to store a buffer, etc.
let offset =
write_message(&header, &mut buffer).expect("Unable to write to buffer!");
let bytes_written_buf = write_message(&msg, &mut buffer[offset..])
.expect("Unable to write to buffer!");
let bytes_written_fd = file
.write(&buffer[..bytes_written_buf + offset])
.map_err(|_| Error::IOError("Cannot write to file descriptor".to_string()))
.expect("Unable to write to file descriptor!");
println!("Wrote {bytes_written_fd} bytes to Fd");
assert_eq!(bytes_written_buf + offset, bytes_written_fd);
let file = PipeWriter::from(writer);
let mut writer = Writer::new(file);
writer.write_messages(&msgs).unwrap();
}
}

Expand Down
23 changes: 10 additions & 13 deletions examples/test_provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
//! on DBus.
//! And that methods can be sent and dealt with appropriately.

use std::{error::Error, io, io::Read, os::fd::OwnedFd};
use std::{error::Error, io, os::fd::OwnedFd};

use spiel::{read_message, Client, Event, EventType, Message};
use spiel::{Client, Event, EventType, Message, Reader};

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
let client = Client::new().await?;
let (mut reader, writer_pipe) = io::pipe()?;
let (reader, writer_pipe) = io::pipe()?;
let writer = OwnedFd::from(writer_pipe);
let providers = client.list_providers().await?;
let mut found = false;
Expand All @@ -18,7 +18,6 @@ async fn main() -> Result<(), Box<dyn Error>> {
continue;
}
found = true;
print!("TRY SEND...");
provider.synthesize(
writer.into(), // pipe writer
"my-voice", // voice ID
Expand All @@ -29,22 +28,20 @@ async fn main() -> Result<(), Box<dyn Error>> {
"en-NZ", // English, New Zealand
)
.await?;
println!("SENT!");
let mut buf = Vec::new();
let bytes_read = reader.read_to_end(&mut buf)?;
println!("BYTES READ: {bytes_read}");
let (bytes_read2, header) = read_message(&buf[..], false)?;
let (bytes_read3, msg) = read_message(&buf[bytes_read2..], true)?;
assert_eq!(bytes_read, bytes_read2 + bytes_read3);
assert_eq!(header, Message::Version("0.01"));
let mut reader =
Reader::from_source(reader).expect("Unable to create reader from pipe!");
let header = reader.try_read().unwrap();
assert_eq!(header, Message::Version("0.01").into_owned());
let event = reader.try_read().unwrap();
assert_eq!(
msg,
event,
Message::Event(Event {
typ: EventType::Word,
start: 69,
end: 420,
name: Some("Hello :)"),
})
.into_owned()
);
break;
}
Expand Down
9 changes: 9 additions & 0 deletions proptest-regressions/proptests.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Seeds for failure cases proptest has generated in the past. It is
# automatically read and these particular cases re-run before any
# novel cases are generated.
#
# It is recommended to check this file in to source control so that
# everyone who runs the test benefits from these saved cases.
cc 8e1f55c50c10fb9f07c393086be490054d60e668b0c2585b8df607d610b52786 # shrinks to msg = Audio([])
cc 5d163de2a6118738e40571964fcfdba119d89c348e62dbea20ea7ca35d600082 # shrinks to msg = Event(Event { typ: Word, start: 0, end: 0, name: None })
cc e0f73a0ff9d3f55330c7b49c5dd7d9ce99795ce3583d4254d96886c489da03ca # shrinks to msg = Event(Event { typ: Word, start: 0, end: 0, name: Some("") })
19 changes: 15 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,9 @@ compile_error!("You need at least 32-bit pointers to use this crate.");
mod protocol;
#[cfg(feature = "poll")]
pub use protocol::poll_read_message;
#[cfg(feature = "reader")]
pub use protocol::Reader;
pub use protocol::{
read_message, read_message_type, write_message, ChunkType, Event, EventType, Message,
MessageType,
read_message, read_message_type, write_message, ChunkType, Error, Event, EventType,
Message, MessageType,
};
#[cfg(feature = "alloc")]
pub use protocol::{EventOwned, MessageOwned};
Expand All @@ -33,3 +31,16 @@ extern crate alloc;
pub mod client;
#[cfg(feature = "client")]
pub use client::{Client, Voice, VoiceFeatureSet};

#[cfg(feature = "reader")]
pub mod reader;
#[cfg(feature = "reader")]
pub use reader::Reader;

#[cfg(all(test, feature = "proptests"))]
pub mod proptests;

#[cfg(feature = "std")]
pub mod writer;
#[cfg(feature = "std")]
pub use writer::Writer;
Loading