Remove Simd-json (#228)

This mirrors the serenity pr https://github.com/serenity-rs/serenity/pull/2735.
This commit is contained in:
Erk
2024-02-29 07:29:20 +01:00
committed by Kyle Simpson
parent c4331c451f
commit c81f2a9578
11 changed files with 32 additions and 72 deletions

View File

@@ -35,7 +35,6 @@ jobs:
- Windows - Windows
- driver only - driver only
- gateway only - gateway only
- simd json
include: include:
- name: beta - name: beta
toolchain: beta toolchain: beta
@@ -53,10 +52,6 @@ jobs:
- name: gateway only - name: gateway only
features: gateway serenity tungstenite rustls features: gateway serenity tungstenite rustls
dont-test: true dont-test: true
- name: simd json
features: simd-json serenity tungstenite rustls driver gateway serenity?/simd_json
rustflags: -C target-cpu=native
dont-test: true
steps: steps:
- name: Checkout sources - name: Checkout sources
uses: actions/checkout@v3 uses: actions/checkout@v3

View File

@@ -41,7 +41,6 @@ serde-aux = { optional = true, version = "4"}
serde_json = "1" serde_json = "1"
serenity = { default-features = false, optional = true, version = "0.12.0", features = ["voice", "gateway"] } serenity = { default-features = false, optional = true, version = "0.12.0", features = ["voice", "gateway"] }
serenity-voice-model = { optional = true, version = "0.2" } serenity-voice-model = { optional = true, version = "0.2" }
simd-json = { features = ["serde_impl"], optional = true, version = "0.13" }
socket2 = { optional = true, version = "0.5" } socket2 = { optional = true, version = "0.5" }
streamcatcher = { optional = true, version = "1" } streamcatcher = { optional = true, version = "1" }
stream_lib = { default-features = false, optional = true, version = "0.4.2" } stream_lib = { default-features = false, optional = true, version = "0.4.2" }

View File

@@ -8,12 +8,6 @@ args = ["fmt", "--all"]
args = ["build", "--features", "full-doc"] args = ["build", "--features", "full-doc"]
dependencies = ["format"] dependencies = ["format"]
[tasks.build-simd]
args = ["build", "--features", "full-doc,simd-json,serenity?/simd_json,twilight-gateway?/simd-json"]
command = "cargo"
dependencies = ["format"]
env = { "RUSTFLAGS" = "-C target-cpu=native" }
[tasks.build-examples] [tasks.build-examples]
args = ["build", "--manifest-path", "./examples/Cargo.toml", "--workspace"] args = ["build", "--manifest-path", "./examples/Cargo.toml", "--workspace"]
command = "cargo" command = "cargo"
@@ -43,11 +37,6 @@ dependencies = ["format"]
[tasks.test] [tasks.test]
args = ["test", "--features", "full-doc", "--", "--include-ignored"] args = ["test", "--features", "full-doc", "--", "--include-ignored"]
[tasks.test-simd]
args = ["test", "--features", "full-doc,simd-json,serenity?/simd_json,twilight-gateway?/simd-json"]
command = "cargo"
env = { "RUSTFLAGS" = "-C target-cpu=native" }
[tasks.bench] [tasks.bench]
description = "Runs performance benchmarks." description = "Runs performance benchmarks."
category = "Test" category = "Test"

View File

@@ -13,7 +13,6 @@ The library offers:
a `ConnectionInfo` using any other gateway, or language for your bot, then you a `ConnectionInfo` using any other gateway, or language for your bot, then you
can run the songbird voice driver. can run the songbird voice driver.
* Voice receive and RT(C)P packet handling via the `"receive"` feature. * Voice receive and RT(C)P packet handling via the `"receive"` feature.
* SIMD-accelerated JSON decoding via the `"simd-json"` feature.
* And, by default, a fully featured voice system featuring events, queues, * And, by default, a fully featured voice system featuring events, queues,
seeking on compatible streams, shared multithreaded audio stream caches, seeking on compatible streams, shared multithreaded audio stream caches,
and direct Opus data passthrough from DCA files. and direct Opus data passthrough from DCA files.

View File

@@ -6,8 +6,6 @@ use futures::channel::mpsc::TrySendError;
pub use serde_json::Error as JsonError; pub use serde_json::Error as JsonError;
#[cfg(feature = "serenity")] #[cfg(feature = "serenity")]
use serenity::gateway::ShardRunnerMessage; use serenity::gateway::ShardRunnerMessage;
#[cfg(feature = "simd-json")]
pub use simd_json::Error as JsonError;
#[cfg(feature = "gateway")] #[cfg(feature = "gateway")]
use std::{error::Error, fmt}; use std::{error::Error, fmt};
#[cfg(feature = "twilight")] #[cfg(feature = "twilight")]

View File

@@ -196,7 +196,7 @@ impl Compressed {
)?; )?;
let mut metabytes = b"DCA1\0\0\0\0".to_vec(); let mut metabytes = b"DCA1\0\0\0\0".to_vec();
let orig_len = metabytes.len(); let orig_len = metabytes.len();
crate::json::to_writer(&mut metabytes, &metadata)?; serde_json::to_writer(&mut metabytes, &metadata)?;
let meta_len = (metabytes.len() - orig_len) let meta_len = (metabytes.len() - orig_len)
.try_into() .try_into()
.map_err(|_| CodecCacheError::MetadataTooLarge)?; .map_err(|_| CodecCacheError::MetadataTooLarge)?;

View File

@@ -109,11 +109,9 @@ impl FormatReader for DcaReader {
return symph_err::decode_error("missing DCA1 metadata block"); return symph_err::decode_error("missing DCA1 metadata block");
} }
let mut raw_json = source.read_boxed_slice_exact(size as usize)?; let raw_json = source.read_boxed_slice_exact(size as usize)?;
// NOTE: must be mut for simd-json. let metadata: DcaMetadata = serde_json::from_slice::<DcaMetadata>(&raw_json)
#[allow(clippy::unnecessary_mut_passed)]
let metadata: DcaMetadata = crate::json::from_slice::<DcaMetadata>(&mut raw_json)
.map_err(|_| SymphError::DecodeError("malformed DCA1 metadata block"))?; .map_err(|_| SymphError::DecodeError("malformed DCA1 metadata block"))?;
let mut revision = MetadataBuilder::new(); let mut revision = MetadataBuilder::new();

View File

@@ -49,7 +49,7 @@ pub struct AuxMetadata {
impl AuxMetadata { impl AuxMetadata {
/// Extract metadata and details from the output of `ffprobe -of json`. /// Extract metadata and details from the output of `ffprobe -of json`.
pub fn from_ffprobe_json(value: &mut [u8]) -> Result<Self, JsonError> { pub fn from_ffprobe_json(value: &mut [u8]) -> Result<Self, JsonError> {
let output: ffprobe::Output = crate::json::from_slice(value)?; let output: ffprobe::Output = serde_json::from_slice(value)?;
Ok(output.into_aux_metadata()) Ok(output.into_aux_metadata())
} }

View File

@@ -164,11 +164,11 @@ impl<'a> YoutubeDl<'a> {
)); ));
} }
// NOTE: must be split_mut for simd-json.
let out = output let out = output
.stdout .stdout
.split_mut(|&b| b == b'\n') .split(|&b| b == b'\n')
.filter_map(|x| (!x.is_empty()).then(|| crate::json::from_slice(x))) .filter(|&x| (!x.is_empty()))
.map(|x| serde_json::from_slice(x))
.collect::<Result<Vec<Output>, _>>() .collect::<Result<Vec<Output>, _>>()
.map_err(|e| AudioStreamError::Fail(Box::new(e)))?; .map_err(|e| AudioStreamError::Fail(Box::new(e)))?;

View File

@@ -113,11 +113,7 @@ pub use discortp as packet;
#[cfg(feature = "driver")] #[cfg(feature = "driver")]
pub use serenity_voice_model as model; pub use serenity_voice_model as model;
// Re-export serde-json APIs locally to minimise conditional config elsewhere.
#[cfg(not(feature = "simd-json"))]
pub(crate) use serde_json as json; pub(crate) use serde_json as json;
#[cfg(feature = "simd-json")]
pub(crate) use simd_json::serde as json;
#[cfg(feature = "driver")] #[cfg(feature = "driver")]
pub use crate::{ pub use crate::{

View File

@@ -128,22 +128,10 @@ impl From<TwsError> for Error {
} }
#[inline] #[inline]
#[allow(unused_unsafe)]
pub(crate) fn convert_ws_message(message: Option<Message>) -> Result<Option<Event>> { pub(crate) fn convert_ws_message(message: Option<Message>) -> Result<Option<Event>> {
#[cfg(feature = "tungstenite")] #[cfg(feature = "tungstenite")]
return Ok(match message { let text = match message {
// SAFETY: Some(Message::Text(ref payload)) => payload,
// simd-json::serde::from_str may leave an &mut str in a non-UTF state on failure.
// The below is safe as we have taken ownership of the inner `String`, and if
// failure occurs we forcibly re-validate its contents before logging.
Some(Message::Text(mut payload)) =>
(unsafe { crate::json::from_str(payload.as_mut_str()) })
.map_err(|e| {
let safe_payload = String::from_utf8_lossy(payload.as_bytes());
debug!("Unexpected JSON: {e}. Payload: {safe_payload}");
e
})
.ok(),
Some(Message::Binary(bytes)) => { Some(Message::Binary(bytes)) => {
return Err(Error::UnexpectedBinaryMessage(bytes)); return Err(Error::UnexpectedBinaryMessage(bytes));
}, },
@@ -151,34 +139,32 @@ pub(crate) fn convert_ws_message(message: Option<Message>) -> Result<Option<Even
return Err(Error::WsClosed(Some(frame))); return Err(Error::WsClosed(Some(frame)));
}, },
// Ping/Pong message behaviour is internally handled by tungstenite. // Ping/Pong message behaviour is internally handled by tungstenite.
_ => None, _ => return Ok(None),
}); };
#[cfg(feature = "tws")] #[cfg(feature = "tws")]
return Ok(if let Some(message) = message { let text = match message {
if message.is_text() { Some(ref message) if message.is_text() =>
let mut payload = message.as_text().unwrap().to_owned(); if let Some(text) = message.as_text() {
// SAFETY: text
// simd-json::serde::from_str may leave an &mut str in a non-UTF state on failure. } else {
// The below is safe as we have created an owned copy of the payload `&str`, and if return Ok(None);
// failure occurs we forcibly re-validate its contents before logging. },
(unsafe { crate::json::from_str(payload.as_mut_str()) }) Some(message) if message.is_binary() => {
.map_err(|e| {
let safe_payload = String::from_utf8_lossy(payload.as_bytes());
debug!("Unexpected JSON: {e}. Payload: {safe_payload}");
e
})
.ok()
} else if message.is_binary() {
return Err(Error::UnexpectedBinaryMessage( return Err(Error::UnexpectedBinaryMessage(
message.into_payload().to_vec(), message.into_payload().to_vec(),
)); ));
} else if message.is_close() { },
Some(message) if message.is_close() => {
return Err(Error::WsClosed(message.as_close().map(|(c, _)| c))); return Err(Error::WsClosed(message.as_close().map(|(c, _)| c)));
} else { },
// ping/pong; will also be internally handled by tokio-websockets // ping/pong; will also be internally handled by tokio-websockets.
None _ => return Ok(None),
} };
} else {
None Ok(serde_json::from_str(text)
}); .map_err(|e| {
debug!("Unexpected JSON: {e}. Payload: {text}");
e
})
.ok())
} }