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