git.delta.rocks / jrsonnet / refs/commits / be790e9c5747

difftreelog

feat byte array specialization

Yaroslav Bolyukin2022-02-12parent: #20cd69c.patch.diff
in: master

2 files changed

modifiedcrates/jrsonnet-evaluator/src/builtin/mod.rsdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/builtin/mod.rs
+++ b/crates/jrsonnet-evaluator/src/builtin/mod.rs
@@ -1,5 +1,5 @@
 use crate::function::StaticBuiltin;
-use crate::typed::{Any, PositiveF64, VecVal, M1};
+use crate::typed::{Any, Bytes, PositiveF64, VecVal, M1};
 use crate::{
 	builtin::manifest::{manifest_yaml_ex, ManifestYamlOptions},
 	equals,
@@ -449,17 +449,15 @@
 }
 
 #[jrsonnet_macros::builtin]
-fn builtin_encode_utf8(str: IStr) -> Result<VecVal> {
-	Ok(VecVal(
-		str.bytes()
-			.map(|b| Val::Num(b as f64))
-			.collect::<Vec<Val>>(),
-	))
+fn builtin_encode_utf8(str: IStr) -> Result<Bytes> {
+	Ok(Bytes(str.bytes().map(|b| b).collect::<Vec<u8>>().into()))
 }
 
 #[jrsonnet_macros::builtin]
-fn builtin_decode_utf8(arr: Vec<u8>) -> Result<String> {
-	Ok(String::from_utf8(arr).map_err(|_| RuntimeError("bad utf8".into()))?)
+fn builtin_decode_utf8(arr: Bytes) -> Result<IStr> {
+	Ok(std::str::from_utf8(&arr.0)
+		.map_err(|_| RuntimeError("bad utf8".into()))?
+		.into())
 }
 
 #[jrsonnet_macros::builtin]
@@ -485,17 +483,21 @@
 }
 
 #[jrsonnet_macros::builtin]
-fn builtin_base64(input: Either![Vec<u8>, IStr]) -> Result<String> {
+fn builtin_base64(input: Either![Bytes, IStr]) -> Result<String> {
 	use Either2::*;
 	Ok(match input {
-		A(a) => base64::encode(a),
+		A(a) => base64::encode(a.0),
 		B(l) => base64::encode(l.bytes().collect::<Vec<_>>()),
 	})
 }
 
 #[jrsonnet_macros::builtin]
-fn builtin_base64_decode_bytes(input: IStr) -> Result<Vec<u8>> {
-	Ok(base64::decode(&input.as_bytes()).map_err(|_| RuntimeError("bad base64".into()))?)
+fn builtin_base64_decode_bytes(input: IStr) -> Result<Bytes> {
+	Ok(Bytes(
+		base64::decode(&input.as_bytes())
+			.map_err(|_| RuntimeError("bad base64".into()))?
+			.into(),
+	))
 }
 
 #[jrsonnet_macros::builtin]
modifiedcrates/jrsonnet-evaluator/src/typed/conversions.rsdiffbeforeafterboth
1use std::convert::{TryFrom, TryInto};1use std::{
2 convert::{TryFrom, TryInto},
3 rc::Rc,
4};
25
3use gcmodule::Cc;6use gcmodule::Cc;
4use jrsonnet_interner::IStr;7use jrsonnet_interner::IStr;
295 }298 }
296}299}
300
301/// Specialization
302pub struct Bytes(pub Rc<[u8]>);
303
304impl Typed for Bytes {
305 const TYPE: &'static ComplexValType =
306 &ComplexValType::ArrayRef(&ComplexValType::BoundedNumber(Some(0.0), Some(255.0)));
307}
308impl TryFrom<Val> for Bytes {
309 type Error = LocError;
310
311 fn try_from(value: Val) -> Result<Self> {
312 match value {
313 Val::Arr(ArrValue::Bytes(bytes)) => Ok(Self(bytes)),
314 _ => {
315 <Self as Typed>::TYPE.check(&value)?;
316 match value {
317 Val::Arr(a) => {
318 let mut out = Vec::with_capacity(a.len());
319 for e in a.iter() {
320 let r = e?;
321 out.push(u8::try_from(r)?);
322 }
323 Ok(Self(out.into()))
324 }
325 _ => unreachable!(),
326 }
327 }
328 }
329 }
330}
331impl TryFrom<Bytes> for Val {
332 type Error = LocError;
333
334 fn try_from(value: Bytes) -> Result<Self> {
335 Ok(Val::Arr(ArrValue::Bytes(value.0)))
336 }
337}
297338
298pub struct M1;339pub struct M1;
299impl Typed for M1 {340impl Typed for M1 {