java_desc/
lib.rs

1use nom::{named, terminated, is_not, char,
2          switch, take, value, map,
3          pair, fold_many_m_n, delimited, many0,
4          alt, combinator::complete};
5
6#[cfg(test)]
7mod tests {
8    use crate::{FieldType, SingleType, MethodType};
9
10    #[test]
11    fn fields() {
12        assert_eq!(FieldType::parse("[[[Lfoo bar net;"), Some(FieldType {
13            base: SingleType::Reference(String::from("foo bar net")), array_cnt: 3
14        }));
15    }
16    #[test]
17    fn methods() {
18        assert_eq!(MethodType::parse("([B[[LFoo;I)[LNetwork;"), Some(MethodType {
19            params: vec![FieldType {
20                base: SingleType::Byte,
21                array_cnt: 1
22            }, FieldType {
23                base: SingleType::Reference(String::from("Foo")),
24                array_cnt: 2
25            }, FieldType {
26                base: SingleType::Int,
27                array_cnt: 0
28            }],
29            ret: Some(FieldType {
30                base: SingleType::Reference(String::from("Network")),
31                array_cnt: 1
32            })
33        }));
34        assert_eq!(MethodType::parse("([B[[LFoo;I)V"), Some(MethodType {
35            params: vec![FieldType {
36                base: SingleType::Byte,
37                array_cnt: 1
38            }, FieldType {
39                base: SingleType::Reference(String::from("Foo")),
40                array_cnt: 2
41            }, FieldType {
42                base: SingleType::Int,
43                array_cnt: 0
44            }],
45            ret: None
46        }))
47    }
48}
49
50named!(semi_terminated<&str, &str>, terminated!(is_not!(";"), char!(';')));
51
52named!(single<&str, SingleType>, switch!(take!(1),
53    "B" => value!(SingleType::Byte) |
54    "C" => value!(SingleType::Char) |
55    "D" => value!(SingleType::Double) |
56    "F" => value!(SingleType::Float) |
57    "I" => value!(SingleType::Int) |
58    "J" => value!(SingleType::Long) |
59    "S" => value!(SingleType::Short) |
60    "Z" => value!(SingleType::Boolean) |
61    "L" => map!(semi_terminated, |v| SingleType::Reference(String::from(v))))
62);
63
64named!(field<&str, FieldType>, map!(
65    pair!(fold_many_m_n!(0, 255, char!('['), 0u8, |v, _| v + 1), single),
66    |v: (u8, SingleType)| FieldType {base: v.1, array_cnt: v.0}
67));
68
69named!(ret<&str, Option<FieldType>>, alt!(
70    map!(field, |v| Some(v)) |
71    map!(char!('V'), |_| None)
72));
73
74named!(method<&str, MethodType>, map!(pair!(
75    delimited!(char!('('), many0!(field), char!(')')),
76    ret),
77    |v| MethodType {params: v.0, ret: v.1}
78));
79
80named!(descriptor<&str, Descriptor>, alt!(
81    map!(method, |v| Descriptor::Method(v)) |
82    map!(field, |v| Descriptor::Field(v))
83));
84
85/// This is an enum, used to represent a base type (without array data)
86#[derive(Debug, Clone, Eq, PartialEq, Hash)]
87pub enum SingleType {
88    Byte,
89    Char,
90    Double,
91    Float,
92    Int,
93    Long,
94    Reference(String),
95    Short,
96    Boolean
97}
98
99impl SingleType {
100    pub fn parse(input: &str) -> Option<Self> {
101        complete(single)(input).ok().map(|v| v.1)
102    }
103}
104
105/// This is a type representing a type descriptor
106#[derive(Debug, Clone, Eq, PartialEq, Hash)]
107pub struct FieldType {
108    pub base: SingleType,
109    pub array_cnt: u8
110}
111
112impl FieldType {
113    pub fn parse(input: &str) -> Option<Self> {
114        complete(field)(input).ok().map(|v| v.1)
115    }
116}
117
118impl From<SingleType> for FieldType {
119    fn from(v: SingleType) -> Self {
120        Self {
121            base: v,
122            array_cnt: 0
123        }
124    }
125}
126
127/// This is a type representing a method descriptor
128#[derive(Debug, Clone, Eq, PartialEq, Hash)]
129pub struct MethodType {
130    pub params: Vec<FieldType>,
131    pub ret: Option<FieldType>
132}
133
134impl MethodType {
135    pub fn parse(input: &str) -> Option<Self> {
136        complete(method)(input).ok().map(|v| v.1)
137    }
138}
139
140/// This is a type representing either a field or method descriptor
141#[derive(Debug, Clone, Eq, PartialEq, Hash)]
142pub enum Descriptor {
143    Field(FieldType),
144    Method(MethodType)
145}
146
147impl Descriptor {
148    pub fn parse(input: &str) -> Option<Self> {
149        complete(descriptor)(input).ok().map(|v| v.1)
150    }
151}
152
153impl From<FieldType> for Descriptor {
154    /// Creates a Signature from a FieldType
155    fn from(v: FieldType) -> Self {
156        Descriptor::Field(v)
157    }
158}
159
160impl From<MethodType> for Descriptor {
161    /// Creates a Signature from a MethodType
162    fn from(v: MethodType) -> Self {
163        Descriptor::Method(v)
164    }
165}