1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
use crate::{ConversionError, ConversionResult, PrimitiveType, Value};
pub trait FromJava: Sized {
fn from_value(value: &Value) -> ConversionResult<Self>;
}
impl<T: FromJava> FromJava for Option<T> {
fn from_value(value: &Value) -> ConversionResult<Self> {
match value {
Value::Null => Ok(None),
_ => Ok(Some(T::from_value(value)?)),
}
}
}
impl FromJava for String {
fn from_value(value: &Value) -> ConversionResult<Self> {
match value {
Value::JavaString(s) => Ok(s.to_string()),
Value::Null => Err(ConversionError::NullPointerException),
_ => Err(ConversionError::InvalidType("string")),
}
}
}
macro_rules! from_value_for_primitive {
($type:ty, $primitive:ident) => {
from_value_for_primitive! {$type, $primitive, stringify!($primitive)}
};
($type:ty, $primitive:ident, $java_name:expr) => {
impl FromJava for $type {
fn from_value(value: &Value) -> ConversionResult<Self> {
match value {
Value::Object(data) => {
let java_class_name = concat!("java.lang.", $java_name);
if data.class_name() == java_class_name {
match data.get_field("value") {
Some(Value::Primitive(PrimitiveType::$primitive(v))) => Ok(*v),
Some(_) => Err(ConversionError::InvalidType(stringify!($type))),
None => Err(ConversionError::FieldNotFound("value".to_string())),
}
} else {
Err(ConversionError::InvalidType(java_class_name))
}
}
Value::Primitive(PrimitiveType::$primitive(i)) => Ok(*i),
_ => Err(ConversionError::InvalidType($java_name)),
}
}
}
};
}
from_value_for_primitive!(u8, Byte);
from_value_for_primitive!(i16, Short);
from_value_for_primitive!(i32, Int, "Integer");
from_value_for_primitive!(i64, Long);
from_value_for_primitive!(f32, Float);
from_value_for_primitive!(f64, Double);
from_value_for_primitive!(char, Char, "Character");
from_value_for_primitive!(bool, Boolean);
impl<T: FromJava> FromJava for Box<T> {
fn from_value(value: &Value) -> ConversionResult<Self> {
Ok(Box::new(T::from_value(value)?))
}
}
impl<T: FromJava> FromJava for Vec<T> {
fn from_value(value: &Value) -> ConversionResult<Self> {
match value {
Value::Array(items) => Ok(items
.iter()
.map(T::from_value)
.collect::<ConversionResult<Vec<_>>>()?),
Value::PrimitiveArray(items) => Ok(items
.iter()
.map(|p| T::from_value(&Value::Primitive(*p)))
.collect::<ConversionResult<Vec<_>>>()?),
_ => Err(ConversionError::InvalidType("array")),
}
}
}