fn from_str(desc: &str) -> Result<TypeDescriptor> {
        // read the string char by char, not bytes
        let mut chars = desc.chars();
        // the array dimensions of the type
        let mut dimensions: u8 = 0;
        // the current location in the descriptor,
        // used to generate better errors
        let mut i = 0;

        // avoid code duplication
        macro_rules! err {
            () => {{
                return Err(Error::InvalidDescriptor {
                    desc: desc.to_owned(),
                    at: i,
                });
            }}
        }

        // read array dimensions and type tag
        loop {
            let ch = match chars.next() {
                Some(ch) => ch,
                None => err!(),
            };

            if ch == '[' {
                // no more than 255 array dimensions are allowed
                dimensions = match dimensions.checked_add(1) {
                    Some(d) => d,
                    None => err!(),
                };
                i += 1;
            } else if ch == 'L' {
                // read name of reference
                break;
            } else {
                // after the primitive tag no chars may be
                if chars.count() != 0 {
                    err!();
                }

                // primitive types can be returned now
                return Ok(TypeDescriptor::new(
                    dimensions,
                    match ch {
                        'Z' => Type::Boolean,
                        'B' => Type::Byte,
                        'S' => Type::Short,
                        'I' => Type::Int,
                        'J' => Type::Long,
                        'F' => Type::Float,
                        'D' => Type::Double,
                        'C' => Type::Char,
                        _ => err!(), // unknown type tag
                    },
                ));
            }
        }

        // A reference descriptor is made up of:
        // [dimensions] L [name] ;
        // There is no need to have a shorter name than this
        // usize.max(usize) is used to prevent panics
        let mut name = String::with_capacity((desc.len() - dimensions as usize).max(2) - 2);

        // now read the name of the reference
        loop {
            let ch = match chars.next() {
                Some(ch) => ch,
                None => err!(),
            };
            i += 1;
            if ch == ';' {
                // a class name cannot be empty, nor can any chars follow the descriptor
                if name.is_empty() || chars.count() != 0 {
                    err!();
                }

                return Ok(TypeDescriptor::new(dimensions, Type::Reference(name)));
            } else {
                name.push(ch);
            }
        }
    }
/// Parses a string and returns a TypeDescriptor if it succeeded.
///
/// # Examples
///
/// ```
/// use jbcrs::{Type, TypeDescriptor};
///
/// let desc: TypeDescriptor = "[[[D".parse().unwrap();
/// assert_eq!(desc, TypeDescriptor { dimensions: 3, base_type: Type::Double });
/// ```
Parses a string and returns a TypeDescriptor if it succeeded.
Parses a string and returns a TypeDescriptor if it succeeded .
fn from_str(desc: &str) -> Result<TypeDescriptor> {
        // read the string char by char, not bytes
        let mut chars = desc.chars();
        // the array dimensions of the type
        let mut dimensions: u8 = 0;
        // the current location in the descriptor,
        // used to generate better errors
        let mut i = 0;
        // avoid code duplication
        macro_rules! err {
            () => {{
                return Err(Error::InvalidDescriptor {
                    desc: desc.to_owned(),
                    at: i,
                });
            }}
        }
        // read array dimensions and type tag
        loop {
            let ch = match chars.next() {
                Some(ch) => ch,
                None => err!(),
            };
            if ch == '[' {
                // no more than 255 array dimensions are allowed
                dimensions = match dimensions.checked_add(1) {
                    Some(d) => d,
                    None => err!(),
                };
                i += 1;
            } else if ch == 'L' {
                // read name of reference
                break;
            } else {
                // after the primitive tag no chars may be
                if chars.count() != 0 {
                    err!();
                }
                // primitive types can be returned now
                return Ok(TypeDescriptor::new(
                    dimensions,
                    match ch {
                        'Z' => Type::Boolean,
                        'B' => Type::Byte,
                        'S' => Type::Short,
                        'I' => Type::Int,
                        'J' => Type::Long,
                        'F' => Type::Float,
                        'D' => Type::Double,
                        'C' => Type::Char,
                        _ => err!(), // unknown type tag
                    },
                ));
            }
        }
        // A reference descriptor is made up of:
        // [dimensions] L [name] ;
        // There is no need to have a shorter name than this
        // usize.max(usize) is used to prevent panics
        let mut name = String::with_capacity((desc.len() - dimensions as usize).max(2) - 2);
        // now read the name of the reference
        loop {
            let ch = match chars.next() {
                Some(ch) => ch,
                None => err!(),
            };
            i += 1;
            if ch == ';' {
                // a class name cannot be empty, nor can any chars follow the descriptor
                if name.is_empty() || chars.count() != 0 {
                    err!();
                }
                return Ok(TypeDescriptor::new(dimensions, Type::Reference(name)));
            } else {
                name.push(ch);
            }
        }
    }
fn from_str ( desc : & str ) -> Result < TypeDescriptor > { // read the string char by char, not bytes let mut chars = desc . chars ( ) ; // the array dimensions of the type let mut dimensions : u8 = 0 ; // the current location in the descriptor, // used to generate better errors let mut i = 0 ; // avoid code duplication macro_rules! err { ( ) => { { return Err ( Error InvalidDescriptor { desc desc to_owned ( ) at i } ) } } } // read array dimensions and type tag loop { let ch = match chars . next ( ) { Some ( ch ) => ch , None => err ! ( ) , } ; if ch == '[' { // no more than 255 array dimensions are allowed dimensions = match dimensions . checked_add ( 1 ) { Some ( d ) => d , None => err ! ( ) , } ; i += 1 ; } else if ch == 'L' { // read name of reference break ; } else { // after the primitive tag no chars may be if chars . count ( ) != 0 { err ! ( ) ; } // primitive types can be returned now return Ok ( TypeDescriptor :: new ( dimensions , match ch { 'Z' => Type :: Boolean , 'B' => Type :: Byte , 'S' => Type :: Short , 'I' => Type :: Int , 'J' => Type :: Long , 'F' => Type :: Float , 'D' => Type :: Double , 'C' => Type :: Char , _ => err ! ( ) , // unknown type tag } , ) ) ; } } // A reference descriptor is made up of: // [dimensions] L [name] ; // There is no need to have a shorter name than this // usize.max(usize) is used to prevent panics let mut name = String :: with_capacity ( ( desc . len ( ) - dimensions as usize ) . max ( 2 ) - 2 ) ; // now read the name of the reference loop { let ch = match chars . next ( ) { Some ( ch ) => ch , None => err ! ( ) , } ; i += 1 ; if ch == ';' { // a class name cannot be empty, nor can any chars follow the descriptor if name . is_empty ( ) || chars . count ( ) != 0 { err ! ( ) ; } return Ok ( TypeDescriptor :: new ( dimensions , Type :: Reference ( name ) ) ) ; } else { name . push ( ch ) ; } } }
Parses a string and returns a TypeDescriptor if it succeeded.
Parses a string and returns a TypeDescriptor if it succeeded .
desc
&str
examples
```
use jbcrs::{Type, TypeDescriptor}.

let desc: TypeDescriptor = "[[[D".parse().unwrap();
assert_eq!(desc, TypeDescriptor { dimensions: 3, base_type: Type::Double });
```
` ` ` use jbcrs :: { Type TypeDescriptor } . let desc : TypeDescriptor = " [[[ D " . parse () . unwrap () ; assert_eq! ( desc TypeDescriptor { dimensions : 3 base_type : Type :: Double } ) ; ` ` `