about summary refs log tree commit diff
diff options
context:
space:
mode:
authoredef <edef@edef.eu>2023-11-10T18·32+0000
committeredef <edef@edef.eu>2023-11-10T19·05+0000
commit4218e4dc0e5834f354b61e31aabc2cb4006d409c (patch)
tree9635b288c82b63fb16101be0ab7146d57c51d7c3
parent7e317cfded5a5eab86111ad485816c3179a34546 (diff)
feat(nix-compat/nixbase32): use data_encoding::DecodeError r/6983
Rather than having our own error type, just make decoding errors use
the same common error type.

Change-Id: Ie2c86972f3745c695253adc3214444ac0ab8db6e
Reviewed-on: https://cl.tvl.fyi/c/depot/+/9995
Reviewed-by: flokli <flokli@flokli.de>
Tested-by: BuildkiteCI
-rw-r--r--tvix/nix-compat/src/narinfo.rs2
-rw-r--r--tvix/nix-compat/src/nixbase32.rs48
-rw-r--r--tvix/nix-compat/src/nixhash/mod.rs2
-rw-r--r--tvix/nix-compat/src/store_path/mod.rs6
4 files changed, 28 insertions, 30 deletions
diff --git a/tvix/nix-compat/src/narinfo.rs b/tvix/nix-compat/src/narinfo.rs
index 4bca115a9578..d10d0d97523f 100644
--- a/tvix/nix-compat/src/narinfo.rs
+++ b/tvix/nix-compat/src/narinfo.rs
@@ -465,7 +465,7 @@ pub enum Error {
     MissingPrefixForHash(String),
 
     #[error("unable to decode {0}: {1}")]
-    UnableToDecodeHash(String, nixbase32::Nixbase32DecodeError),
+    UnableToDecodeHash(String, data_encoding::DecodeError),
 
     #[error("unable to parse signature #{0}: {1}")]
     UnableToParseSignature(usize, SignatureError),
diff --git a/tvix/nix-compat/src/nixbase32.rs b/tvix/nix-compat/src/nixbase32.rs
index babf768addf2..79b4750d9509 100644
--- a/tvix/nix-compat/src/nixbase32.rs
+++ b/tvix/nix-compat/src/nixbase32.rs
@@ -9,21 +9,10 @@
 
 use std::fmt::Write;
 
-use thiserror::Error;
+use data_encoding::{DecodeError, DecodeKind};
 
 const ALPHABET: &[u8; 32] = b"0123456789abcdfghijklmnpqrsvwxyz";
 
-/// Errors that can occur while decoding nixbase32-encoded data.
-#[derive(Debug, Eq, PartialEq, Error)]
-pub enum Nixbase32DecodeError {
-    #[error("character {0:x} not in alphabet")]
-    CharacterNotInAlphabet(u8),
-    #[error("nonzero carry")]
-    NonzeroCarry,
-    #[error("invalid length")]
-    InvalidLength,
-}
-
 /// Returns encoded input
 pub fn encode(input: &[u8]) -> String {
     let output_len = encode_len(input.len());
@@ -69,7 +58,7 @@ const BASE32_ORD: [u8; 256] = {
 };
 
 /// Returns decoded input
-pub fn decode(input: impl AsRef<[u8]>) -> Result<Vec<u8>, Nixbase32DecodeError> {
+pub fn decode(input: impl AsRef<[u8]>) -> Result<Vec<u8>, DecodeError> {
     let input = input.as_ref();
 
     let output_len = decode_len(input.len());
@@ -79,13 +68,14 @@ pub fn decode(input: impl AsRef<[u8]>) -> Result<Vec<u8>, Nixbase32DecodeError>
     Ok(output)
 }
 
-pub fn decode_fixed<const K: usize>(
-    input: impl AsRef<[u8]>,
-) -> Result<[u8; K], Nixbase32DecodeError> {
+pub fn decode_fixed<const K: usize>(input: impl AsRef<[u8]>) -> Result<[u8; K], DecodeError> {
     let input = input.as_ref();
 
     if input.len() != encode_len(K) {
-        return Err(Nixbase32DecodeError::InvalidLength);
+        return Err(DecodeError {
+            position: input.len().min(encode_len(K)),
+            kind: DecodeKind::Length,
+        });
     }
 
     let mut output = [0; K];
@@ -93,7 +83,7 @@ pub fn decode_fixed<const K: usize>(
     Ok(output)
 }
 
-fn decode_inner(input: &[u8], output: &mut [u8]) -> Result<(), Nixbase32DecodeError> {
+fn decode_inner(input: &[u8], output: &mut [u8]) -> Result<(), DecodeError> {
     // loop over all characters in reverse, and keep the iteration count in n.
     let mut carry = 0;
     let mut mask = 0;
@@ -111,22 +101,27 @@ fn decode_inner(input: &[u8], output: &mut [u8]) -> Result<(), Nixbase32DecodeEr
     }
 
     if mask == 0xFF {
-        let c = find_invalid(input);
-        return Err(Nixbase32DecodeError::CharacterNotInAlphabet(c));
+        return Err(DecodeError {
+            position: find_invalid(input),
+            kind: DecodeKind::Symbol,
+        });
     }
 
     // if we're at the end, but have a nonzero carry, the encoding is invalid.
     if carry != 0 {
-        return Err(Nixbase32DecodeError::NonzeroCarry);
+        return Err(DecodeError {
+            position: 0,
+            kind: DecodeKind::Trailing,
+        });
     }
 
     Ok(())
 }
 
-fn find_invalid(input: &[u8]) -> u8 {
-    for &c in input {
+fn find_invalid(input: &[u8]) -> usize {
+    for (i, &c) in input.iter().enumerate() {
         if !ALPHABET.contains(&c) {
-            return c;
+            return i;
         }
     }
 
@@ -187,7 +182,10 @@ mod tests {
         );
         assert_eq!(
             super::decode_fixed::<32>("00").unwrap_err(),
-            super::Nixbase32DecodeError::InvalidLength
+            super::DecodeError {
+                position: 2,
+                kind: super::DecodeKind::Length
+            }
         );
     }
 
diff --git a/tvix/nix-compat/src/nixhash/mod.rs b/tvix/nix-compat/src/nixhash/mod.rs
index d2c1d0bd2017..f699a4cd9524 100644
--- a/tvix/nix-compat/src/nixhash/mod.rs
+++ b/tvix/nix-compat/src/nixhash/mod.rs
@@ -92,7 +92,7 @@ pub enum Error {
     #[error("invalid base16 encoding: {0}")]
     InvalidBase16Encoding(data_encoding::DecodeError),
     #[error("invalid base32 encoding: {0}")]
-    InvalidBase32Encoding(nixbase32::Nixbase32DecodeError),
+    InvalidBase32Encoding(data_encoding::DecodeError),
     #[error("invalid base64 encoding: {0}")]
     InvalidBase64Encoding(data_encoding::DecodeError),
     #[error("conflicting hash algo: {0} (hash_algo) vs {1} (inline)")]
diff --git a/tvix/nix-compat/src/store_path/mod.rs b/tvix/nix-compat/src/store_path/mod.rs
index fe4cf9f5830a..3eb8877d6efd 100644
--- a/tvix/nix-compat/src/store_path/mod.rs
+++ b/tvix/nix-compat/src/store_path/mod.rs
@@ -1,5 +1,5 @@
-use crate::nixbase32::{self, Nixbase32DecodeError};
-use data_encoding::BASE64;
+use crate::nixbase32;
+use data_encoding::{DecodeError, BASE64};
 use std::{
     fmt,
     path::PathBuf,
@@ -28,7 +28,7 @@ pub enum Error {
     #[error("Dash is missing between hash and name")]
     MissingDash,
     #[error("Hash encoding is invalid: {0}")]
-    InvalidHashEncoding(Nixbase32DecodeError),
+    InvalidHashEncoding(DecodeError),
     #[error("Invalid length")]
     InvalidLength,
     #[error(