Panicked at 'assertion failed: chunk.is_err()'

Hello everyone,
I have just completed reading and practicing, most of the documentation for from the learn section on the website called the-book, i wanted to try to learn the language by doing a project, someone suggested me the pngme as a good project, I was able to pass 13 cases with one failing, I have been sitting on my system for hours unable to get what it means the means to solve it,

png-me: Introduction - PNGme: An Intermediate Rust Project

The error

failures:

---- chunk_type::tests::test_invalid_chunk_is_valid stdout ----
thread 'chunk_type::tests::test_invalid_chunk_is_valid' panicked at 'assertion failed: chunk.is_err()', src/chunk_type.rs:192
:9

Here is the code for
chunk_type.rs

#![allow(unused_variables)]
use std::fmt;
use std::str::FromStr;
use std::{convert::TryFrom, u8};

use crate::{Error, Result};

/// A validated PNG chunk type. See the PNG spec for more details.
/// http://www.libpng.org/pub/png/spec/1.2/PNG-Structure.html
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ChunkType {
    data: String,
}

impl ChunkType {
    // / Returns the raw bytes contained in this chunk
    pub fn bytes(&self) -> [u8; 4] {
        let result = self.data.as_bytes().try_into().unwrap();
        result
    }

    /// Returns the property state of the first byte as described in the PNG spec
    pub fn is_critical(&self) -> bool {
        let first_byte: &[u8] = self.data[0..1].as_bytes();
        first_byte[0].is_ascii_uppercase()
    }

    /// Returns the property state of the second byte as described in the PNG spec
    pub fn is_public(&self) -> bool {
        let second_byte: &[u8] = self.data[1..2].as_bytes();
        second_byte[0].is_ascii_uppercase()
    }

    /// Returns the property state of the third byte as described in the PNG spec
    pub fn is_reserved_bit_valid(&self) -> bool {
        let third_byte: &[u8] = self.data[2..3].as_bytes();
        third_byte[0].is_ascii_uppercase()
    }

    /// Returns the property state of the fourth byte as described in the PNG spec
    pub fn is_safe_to_copy(&self) -> bool {
        let fourth_byte: &[u8] = self.data[3..].as_bytes();
        fourth_byte[0].is_ascii_lowercase()
    }

    /// Returns true if the reserved byte is valid and all four bytes are represented by the characters A-Z or a-z.
    /// Note that this chunk type should always be valid as it is validated during construction.
    pub fn is_valid(&self) -> bool {
        let data_as_bytes: &[u8] = &self.data[..].as_bytes();
        let mut flag = 0;
        for ascii_val in data_as_bytes {
            if ChunkType::is_valid_byte(ascii_val.to_owned()) {
                continue;
            } else {
                flag = 1;
                break;
            }
        }
        if flag == 1 || !self.is_reserved_bit_valid() {
            return false;
        } else {
            return true;
        }
    }

    /// Valid bytes are represented by the characters A-Z or a-z

    pub fn is_valid_byte(ascii_val: u8) -> bool {
        let mut valid_bytes: Vec<u8> = (b'A'..b'[').collect();
        let mut something: Vec<u8> = (b'a'..b'{').collect();
        valid_bytes.append(&mut something);
        // println!("{:?}", valid_bytes);
        valid_bytes.contains(&ascii_val)
        // (ascii_val >= b'A' && ascii_val <= b'Z') || (ascii_val >= b'a' && ascii_val <= b'z')
    }
}
impl TryFrom<[u8; 4]> for ChunkType {
    type Error = Error;

    fn try_from(bytes: [u8; 4]) -> Result<Self> {
        let string: String = String::from_utf8(bytes[..].into()).unwrap();
        let chunk = ChunkType { data: string };
        if chunk.is_valid() {
            return Ok(chunk);
        } else {
            return Err("The chunk is not valid".into());
        }
    }
}

impl fmt::Display for ChunkType {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", self.data)
    }
}

impl FromStr for ChunkType {
    type Err = Error;

    fn from_str(s: &str) -> Result<Self> {
        if s.len() == 4 {
            let chunk: String = s.to_string();
            let result_chunk = ChunkType { data: chunk };
            Ok(result_chunk)
        } else {
            return Err("Expected 4 bytes, recived a diff number".into());
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::convert::TryFrom;
    use std::str::FromStr;

    #[test]
    pub fn test_chunk_type_from_bytes() {
        let expected = [82, 117, 83, 116];
        let actual = ChunkType::try_from([82, 117, 83, 116]).unwrap();

        assert_eq!(expected, actual.bytes());
    }

    #[test]
    pub fn test_chunk_type_from_str() {
        let expected = ChunkType::try_from([82, 117, 83, 116]).unwrap();
        let actual = ChunkType::from_str("RuSt").unwrap();
        assert_eq!(expected, actual);
    }

    #[test]
    pub fn test_chunk_type_is_critical() {
        let chunk = ChunkType::from_str("RuSt").unwrap();
        assert!(chunk.is_critical());
    }

    #[test]
    pub fn test_chunk_type_is_not_critical() {
        let chunk = ChunkType::from_str("ruSt").unwrap();
        assert!(!chunk.is_critical());
    }

    #[test]
    pub fn test_chunk_type_is_public() {
        let chunk = ChunkType::from_str("RUSt").unwrap();
        assert!(chunk.is_public());
    }

    #[test]
    pub fn test_chunk_type_is_not_public() {
        let chunk = ChunkType::from_str("RuSt").unwrap();
        assert!(!chunk.is_public());
    }

    #[test]
    pub fn test_chunk_type_is_reserved_bit_valid() {
        let chunk = ChunkType::from_str("RuSt").unwrap();
        assert!(chunk.is_reserved_bit_valid());
    }

    #[test]
    pub fn test_chunk_type_is_reserved_bit_invalid() {
        let chunk = ChunkType::from_str("Rust").unwrap();
        assert!(!chunk.is_reserved_bit_valid());
    }

    #[test]
    pub fn test_chunk_type_is_safe_to_copy() {
        let chunk = ChunkType::from_str("RuSt").unwrap();
        assert!(chunk.is_safe_to_copy());
    }

    #[test]
    pub fn test_chunk_type_is_unsafe_to_copy() {
        let chunk = ChunkType::from_str("RuST").unwrap();
        assert!(!chunk.is_safe_to_copy());
    }

    #[test]
    pub fn test_valid_chunk_is_valid() {
        let chunk = ChunkType::from_str("RuSt").unwrap();
        assert!(chunk.is_valid());
    }

    #[test]
    pub fn test_invalid_chunk_is_valid() {
        let chunk = ChunkType::from_str("Rust").unwrap();
        assert!(!chunk.is_valid());

        let chunk = ChunkType::from_str("Ru1t");
        assert!(chunk.is_err());
    }

    #[test]
    pub fn test_chunk_type_string() {
        let chunk = ChunkType::from_str("RuSt").unwrap();
        assert_eq!(&chunk.to_string(), "RuSt");
    }

    #[test]
    pub fn test_chunk_type_trait_impls() {
        let chunk_type_1: ChunkType = TryFrom::try_from([82, 117, 83, 116]).unwrap();
        let chunk_type_2: ChunkType = FromStr::from_str("RuSt").unwrap();
        let _chunk_string = format!("{}", chunk_type_1);
        let _are_chunks_equal = chunk_type_1 == chunk_type_2;
    }
}

It would be great if you could help me with this, or give me any suggestions
Thank you.

The test in question is

        let chunk = ChunkType::from_str("Ru1t");
        assert!(chunk.is_err());

and the corresponding code is

impl FromStr for ChunkType {
    type Err = Error;

    fn from_str(s: &str) -> Result<Self> {
        if s.len() == 4 {
            let chunk: String = s.to_string();
            let result_chunk = ChunkType { data: chunk };
            Ok(result_chunk)
        } else {
            return Err("Expected 4 bytes, recived a diff number".into());
        }
    }
}

This always returns an Ok variant when the length is 4, and the string "Ru1t" is indeed of length 4.

Thanks for the reply, i think my implementation of the code was wrong, I'll try rewriting my code in a better way :slight_smile:

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.