fn from_str(desc: &str) -> Result<MethodDescriptor> {
        let mut chars = desc.chars();
        let mut i = 0;

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

        match chars.next() {
            Some('(') => {}
            _ => err!(),
        }

        let mut params = Vec::new();
        let mut ret = None;
        let mut state = 0;

        // sorry for this messy code
        'type_loop: loop {
            let mut dimensions: u8 = 0;

            // read array dimensions and type tag
            for ch in &mut chars {
                i += 1;
                if ch == '[' {
                    // no more than 255 array dimensions are allowed
                    dimensions = match dimensions.checked_add(1) {
                        Some(d) => d,
                        None => err!(),
                    };
                } else if state == 0 && ch == ')' {
                    if dimensions != 0 {
                        err!();
                    }
                    state = 1;
                } else if state == 1 && ch == 'V' {
                    if dimensions != 0 {
                        err!();
                    }

                    break 'type_loop;
                } else {
                    let parsed_desc = 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,
                            'L' => break, // read the name of the reference
                            _ => err!(),  // unknown type tag
                        },
                    );

                    if state == 0 {
                        params.push(parsed_desc);
                        continue 'type_loop;
                    } else {
                        ret = Some(parsed_desc);
                        break 'type_loop;
                    }
                }
            }

            let mut name = String::new();

            // now read the name of the reference
            for ch in &mut chars {
                i += 1;
                if ch == ';' {
                    if name.is_empty() {
                        err!();
                    }

                    let parsed_desc = TypeDescriptor::new(dimensions, Type::Reference(name));
                    if state == 0 {
                        params.push(parsed_desc);
                        continue 'type_loop;
                    } else {
                        ret = Some(parsed_desc);
                        break 'type_loop;
                    }
                } else {
                    name.push(ch);
                }
            }

            err!();
        }

        if chars.count() != 0 || params.len() > 255 {
            err!();
        }

        Ok(MethodDescriptor::new(params, ret))
    }
/// Parses a string and returns a MethodDescriptor if it succeeded.
///
/// # Examples
///
/// ```
/// use jbcrs::{Type, TypeDescriptor, MethodDescriptor};
///
/// let desc: MethodDescriptor = "([[DLjava/lang/Integer;)V".parse().unwrap();
/// assert_eq!(desc, MethodDescriptor {
///     params: vec![
///         TypeDescriptor {
///             dimensions: 2,
///             base_type: Type::Double,
///         },
///         TypeDescriptor {
///             dimensions: 0,
///             base_type: Type::Reference("java/lang/Integer".to_owned()),
///         },
///     ],
///     return_type: None,
/// });
/// ```
Parses a string and returns a MethodDescriptor if it succeeded.
Parses a string and returns a MethodDescriptor if it succeeded .
fn from_str(desc: &str) -> Result<MethodDescriptor> {
        let mut chars = desc.chars();
        let mut i = 0;
        // avoid code duplication
        macro_rules! err {
            () => {{
                return Err(Error::InvalidDescriptor {
                    desc: desc.to_owned(),
                    at: i,
                });
            }}
        }
        match chars.next() {
            Some('(') => {}
            _ => err!(),
        }
        let mut params = Vec::new();
        let mut ret = None;
        let mut state = 0;
        // sorry for this messy code
        'type_loop: loop {
            let mut dimensions: u8 = 0;
            // read array dimensions and type tag
            for ch in &mut chars {
                i += 1;
                if ch == '[' {
                    // no more than 255 array dimensions are allowed
                    dimensions = match dimensions.checked_add(1) {
                        Some(d) => d,
                        None => err!(),
                    };
                } else if state == 0 && ch == ')' {
                    if dimensions != 0 {
                        err!();
                    }
                    state = 1;
                } else if state == 1 && ch == 'V' {
                    if dimensions != 0 {
                        err!();
                    }
                    break 'type_loop;
                } else {
                    let parsed_desc = 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,
                            'L' => break, // read the name of the reference
                            _ => err!(),  // unknown type tag
                        },
                    );
                    if state == 0 {
                        params.push(parsed_desc);
                        continue 'type_loop;
                    } else {
                        ret = Some(parsed_desc);
                        break 'type_loop;
                    }
                }
            }
            let mut name = String::new();
            // now read the name of the reference
            for ch in &mut chars {
                i += 1;
                if ch == ';' {
                    if name.is_empty() {
                        err!();
                    }
                    let parsed_desc = TypeDescriptor::new(dimensions, Type::Reference(name));
                    if state == 0 {
                        params.push(parsed_desc);
                        continue 'type_loop;
                    } else {
                        ret = Some(parsed_desc);
                        break 'type_loop;
                    }
                } else {
                    name.push(ch);
                }
            }
            err!();
        }
        if chars.count() != 0 || params.len() > 255 {
            err!();
        }
        Ok(MethodDescriptor::new(params, ret))
    }
fn from_str ( desc : & str ) -> Result < MethodDescriptor > { let mut chars = desc . chars ( ) ; let mut i = 0 ; // avoid code duplication macro_rules! err { ( ) => { { return Err ( Error InvalidDescriptor { desc desc to_owned ( ) at i } ) } } } match chars . next ( ) { Some ( '(' ) => { } _ => err ! ( ) , } let mut params = Vec :: new ( ) ; let mut ret = None ; let mut state = 0 ; // sorry for this messy code ' type_loop : loop { let mut dimensions : u8 = 0 ; // read array dimensions and type tag for ch in & mut chars { i += 1 ; if ch == '[' { // no more than 255 array dimensions are allowed dimensions = match dimensions . checked_add ( 1 ) { Some ( d ) => d , None => err ! ( ) , } ; } else if state == 0 && ch == ')' { if dimensions != 0 { err ! ( ) ; } state = 1 ; } else if state == 1 && ch == 'V' { if dimensions != 0 { err ! ( ) ; } break ' type_loop ; } else { let parsed_desc = 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 , 'L' => break , // read the name of the reference _ => err ! ( ) , // unknown type tag } , ) ; if state == 0 { params . push ( parsed_desc ) ; continue ' type_loop ; } else { ret = Some ( parsed_desc ) ; break ' type_loop ; } } } let mut name = String :: new ( ) ; // now read the name of the reference for ch in & mut chars { i += 1 ; if ch == ';' { if name . is_empty ( ) { err ! ( ) ; } let parsed_desc = TypeDescriptor :: new ( dimensions , Type :: Reference ( name ) ) ; if state == 0 { params . push ( parsed_desc ) ; continue ' type_loop ; } else { ret = Some ( parsed_desc ) ; break ' type_loop ; } } else { name . push ( ch ) ; } } err ! ( ) ; } if chars . count ( ) != 0 || params . len ( ) > 255 { err ! ( ) ; } Ok ( MethodDescriptor :: new ( params , ret ) ) }
Parses a string and returns a MethodDescriptor if it succeeded.
Parses a string and returns a MethodDescriptor if it succeeded .
desc
&str
examples
```
use jbcrs::{Type, TypeDescriptor, MethodDescriptor}.

let desc: MethodDescriptor = "([[DLjava/lang/Integer;)V".parse().unwrap();
assert_eq!(desc, MethodDescriptor {
params: vec![
TypeDescriptor {
dimensions: 2,
base_type: Type::Double,
},
TypeDescriptor {
dimensions: 0,
base_type: Type::Reference("java/lang/Integer".to_owned()),
},
],
return_type: None,
});
```
` ` ` use jbcrs :: { Type TypeDescriptor MethodDescriptor } . let desc : MethodDescriptor = " ( [[ DLjava / lang / Integer ; ) V " . parse () . unwrap () ; assert_eq! ( desc MethodDescriptor { params : vec! [ TypeDescriptor { dimensions : 2 base_type : Type :: Double } TypeDescriptor { dimensions : 0 base_type : Type :: Reference ( " java / lang / Integer " . to_owned () ) } ] return_type : None } ) ; ` ` `