///|
fn[T] decode_type_error(
path : RonPath,
expected : String,
value : RonValue,
) -> T raise RonDecodeError {
raise TypeMismatch(path, expected, value_type_name(value))
}
///|
fn as_number(
value : RonValue,
path : RonPath,
expected : String,
) -> RonNumber raise RonDecodeError {
match value {
Number(number) => number
_ => decode_type_error(path, expected, value)
}
}
///|
pub impl ToRon for Unit with fn to_ron(_, _) {
Unit
}
///|
pub impl FromRon for Unit with fn from_ron(value, path, _) {
match value {
Unit => ()
_ => decode_type_error(path, "unit", value)
}
}
///|
pub impl ToRon for Bool with fn to_ron(self, _) {
Bool(self)
}
///|
pub impl FromRon for Bool with fn from_ron(value, path, _) {
match value {
Bool(value) => value
_ => decode_type_error(path, "bool", value)
}
}
///|
pub impl ToRon for Byte with fn to_ron(self, _) {
Number(Signed(self.to_int64()))
}
///|
pub impl FromRon for Byte with fn from_ron(value, path, _) {
match as_number(value, path, "Byte") {
Signed(value) if value >= 0L && value <= 255L => value.to_int().to_byte()
Unsigned(value) if value <= 255UL => value.to_int().to_byte()
_ => raise InvalidValue(path, "byte out of range")
}
}
///|
pub impl ToRon for Int32 with fn to_ron(self, _) {
Number(Signed(self.to_int64()))
}
///|
pub impl FromRon for Int32 with fn from_ron(value, path, _) {
match as_number(value, path, "Int") {
Signed(value) if value >= -2147483648L && value <= 2147483647L =>
value.to_int()
Unsigned(value) if value <= 2147483647UL => value.to_int()
_ => raise InvalidValue(path, "Int out of range")
}
}
///|
pub impl ToRon for Int64 with fn to_ron(self, _) {
Number(Signed(self))
}
///|
pub impl FromRon for Int64 with fn from_ron(value, path, _) {
match as_number(value, path, "Int64") {
Signed(value) => value
Unsigned(value) if value <= 0x7fffffffffffffffUL =>
value.reinterpret_as_int64()
_ => raise InvalidValue(path, "Int64 out of range")
}
}
///|
pub impl ToRon for UInt32 with fn to_ron(self, _) {
Number(Unsigned(self.to_uint64()))
}
///|
pub impl FromRon for UInt32 with fn from_ron(value, path, _) {
match as_number(value, path, "UInt") {
Signed(value) if value >= 0L && value <= 4294967295L =>
value.to_int().reinterpret_as_uint()
Unsigned(value) if value <= 4294967295UL =>
value.to_int().reinterpret_as_uint()
_ => raise InvalidValue(path, "UInt out of range")
}
}
///|
pub impl ToRon for UInt64 with fn to_ron(self, _) {
Number(Unsigned(self))
}
///|
pub impl FromRon for UInt64 with fn from_ron(value, path, _) {
match as_number(value, path, "UInt64") {
Signed(value) if value >= 0L => value.reinterpret_as_uint64()
Unsigned(value) => value
_ => raise InvalidValue(path, "UInt64 out of range")
}
}
///|
pub impl ToRon for Int16 with fn to_ron(self, _) {
Number(Signed(self.to_int64()))
}
///|
pub impl FromRon for Int16 with fn from_ron(value, path, _) {
match as_number(value, path, "Int16") {
Signed(value) if value >= -32768L && value <= 32767L =>
Int16::from_int(value.to_int())
Unsigned(value) if value <= 32767UL => Int16::from_int(value.to_int())
_ => raise InvalidValue(path, "Int16 out of range")
}
}
///|
pub impl ToRon for UInt16 with fn to_ron(self, _) {
Number(Unsigned(self.to_uint64()))
}
///|
pub impl FromRon for UInt16 with fn from_ron(value, path, _) {
match as_number(value, path, "UInt16") {
Signed(value) if value >= 0L && value <= 65535L =>
value.to_int().to_uint16()
Unsigned(value) if value <= 65535UL => value.to_int().to_uint16()
_ => raise InvalidValue(path, "UInt16 out of range")
}
}
///|
pub impl ToRon for Double with fn to_ron(self, _) {
if self.is_nan() {
Number(NaN)
} else if self.is_pos_inf() {
Number(Infinity)
} else if self.is_neg_inf() {
Number(NegativeInfinity)
} else {
Number(Float(self))
}
}
///|
pub impl FromRon for Double with fn from_ron(value, path, _) {
match as_number(value, path, "Double") {
Signed(value) => value.to_double()
Unsigned(value) => value.to_double()
Float(value) => value
Infinity => @double.infinity
NegativeInfinity => @double.neg_infinity
NaN => @double.not_a_number
}
}
///|
pub impl ToRon for Float with fn to_ron(self, _) {
if self.is_nan() {
Number(NaN)
} else if self.is_pos_inf() {
Number(Infinity)
} else if self.is_neg_inf() {
Number(NegativeInfinity)
} else {
Number(Float(self.to_double()))
}
}
///|
pub impl FromRon for Float with fn from_ron(value, path, _) {
match as_number(value, path, "Float") {
Signed(value) => Float::from_int64(value)
Unsigned(value) => Float::from_uint64(value)
Float(value) => Float::from_double(value)
Infinity => @float.infinity
NegativeInfinity => @float.neg_infinity
NaN => @float.not_a_number
}
}
///|
pub impl ToRon for Char with fn to_ron(self, _) {
Char(self)
}
///|
pub impl FromRon for Char with fn from_ron(value, path, _) {
match value {
Char(value) => value
_ => decode_type_error(path, "char", value)
}
}
///|
pub impl ToRon for String with fn to_ron(self, _) {
String(self)
}
///|
pub impl FromRon for String with fn from_ron(value, path, _) {
match value {
String(value) => value
_ => decode_type_error(path, "string", value)
}
}
///|
pub impl ToRon for Bytes with fn to_ron(self, _) {
Bytes(self)
}
///|
pub impl FromRon for Bytes with fn from_ron(value, path, _) {
match value {
Bytes(value) => value
_ => decode_type_error(path, "bytes", value)
}
}
///|
pub impl ToRon for RonValue with fn to_ron(self, _) {
self
}
///|
pub impl FromRon for RonValue with fn from_ron(value, _, _) {
value
}
///|
pub impl ToRon for RonRange with fn to_ron(self, _) {
Range(self)
}
///|
pub impl FromRon for RonRange with fn from_ron(value, path, _) {
match value {
Range(range) => range
_ => decode_type_error(path, "range", value)
}
}
///|
pub impl[T : ToRon] ToRon for T? with fn to_ron(self, options) {
match self {
None => Option(None)
Some(value) =>
if options.extensions.implicit_some {
ToRon::to_ron(value, options)
} else {
Option(Some(ToRon::to_ron(value, options)))
}
}
}
///|
pub impl[T : FromRon] FromRon for T? with fn from_ron(value, path, options) {
match value {
Option(None) => None
Option(Some(value)) =>
Some(FromRon::from_ron(value, path.add_variant("Some"), options))
_ if options.extensions.implicit_some =>
Some(FromRon::from_ron(value, path.add_variant("Some"), options))
_ => decode_type_error(path, "option", value)
}
}
///|
pub impl[T : ToRon] ToRon for Array[T] with fn to_ron(self, options) {
Sequence(self.map(value => ToRon::to_ron(value, options)))
}
///|
pub impl[T : FromRon] FromRon for Array[T] with fn from_ron(
value,
path,
options,
) {
match value {
Sequence(values) => {
let result = []
for i = 0; i < values.length(); i = i + 1 {
result.push(FromRon::from_ron(values[i], path.add_index(i), options))
}
result
}
_ => decode_type_error(path, "sequence", value)
}
}
///|
pub impl[T : ToRon] ToRon for FixedArray[T] with fn to_ron(self, options) {
Sequence(
Array::from_fixed_array(self.map(value => ToRon::to_ron(value, options))),
)
}
///|
pub impl[T : FromRon] FromRon for FixedArray[T] with fn from_ron(
value,
path,
options,
) {
match value {
Sequence(values) => {
let result = []
for i = 0; i < values.length(); i = i + 1 {
result.push(FromRon::from_ron(values[i], path.add_index(i), options))
}
FixedArray::from_array(result)
}
_ => decode_type_error(path, "fixed array", value)
}
}
///|
pub impl[T : ToRon] ToRon for ArrayView[T] with fn to_ron(self, options) {
Sequence(self.to_owned().map(value => ToRon::to_ron(value, options)))
}
///|
pub impl[V : ToRon] ToRon for Map[String, V] with fn to_ron(self, options) {
let entries = self.to_array()
entries.sort_by((left, right) => left.0.compare(right.0))
Map(entries.map(entry => (String(entry.0), ToRon::to_ron(entry.1, options))))
}
///|
pub impl[V : FromRon] FromRon for Map[String, V] with fn from_ron(
value,
path,
options,
) {
match value {
Map(entries) => {
let result : Map[String, V] = Map([])
for i = 0; i < entries.length(); i = i + 1 {
let (key, value) = entries[i]
let key = match key {
String(key) | Identifier(key) => key
_ =>
raise TypeMismatch(
path.add_index(i),
"string key",
value_type_name(key),
)
}
result[key] = FromRon::from_ron(value, path.add_key(key), options)
}
result
}
_ => decode_type_error(path, "map", value)
}
}
///|
pub impl[Ok : ToRon, Err : ToRon] ToRon for Result[Ok, Err] with fn to_ron(
self,
options,
) {
match self {
Ok(value) => TupleStruct("Ok", [ToRon::to_ron(value, options)])
Err(error) => TupleStruct("Err", [ToRon::to_ron(error, options)])
}
}
///|
pub impl[Ok : FromRon, Err : FromRon] FromRon for Result[Ok, Err] with fn from_ron(
value,
path,
options,
) {
match value {
TupleStruct("Ok", values) if values.length() == 1 =>
Ok(FromRon::from_ron(values[0], path.add_variant("Ok"), options))
TupleStruct("Err", values) if values.length() == 1 =>
Err(FromRon::from_ron(values[0], path.add_variant("Err"), options))
EnumTuple(_, "Ok", values) if values.length() == 1 =>
Ok(FromRon::from_ron(values[0], path.add_variant("Ok"), options))
EnumTuple(_, "Err", values) if values.length() == 1 =>
Err(FromRon::from_ron(values[0], path.add_variant("Err"), options))
_ => raise InvalidValue(path, "expected Result variant Ok or Err")
}
}
///|
pub impl[A : ToRon, B : ToRon] ToRon for (A, B) with fn to_ron(self, options) {
Tuple([ToRon::to_ron(self.0, options), ToRon::to_ron(self.1, options)])
}
///|
pub impl[A : FromRon, B : FromRon] FromRon for (A, B) with fn from_ron(
value,
path,
options,
) {
match value {
Tuple(values) if values.length() == 2 =>
(
FromRon::from_ron(values[0], path.add_index(0), options),
FromRon::from_ron(values[1], path.add_index(1), options),
)
Tuple(values) => raise UnexpectedTupleLength(path, 2, values.length())
_ => decode_type_error(path, "tuple", value)
}
}
///|
pub impl[A : ToRon, B : ToRon, C : ToRon] ToRon for (A, B, C) with fn to_ron(
self,
options,
) {
Tuple([
ToRon::to_ron(self.0, options),
ToRon::to_ron(self.1, options),
ToRon::to_ron(self.2, options),
])
}
///|
pub impl[A : FromRon, B : FromRon, C : FromRon] FromRon for (A, B, C) with fn from_ron(
value,
path,
options,
) {
match value {
Tuple(values) if values.length() == 3 =>
(
FromRon::from_ron(values[0], path.add_index(0), options),
FromRon::from_ron(values[1], path.add_index(1), options),
FromRon::from_ron(values[2], path.add_index(2), options),
)
Tuple(values) => raise UnexpectedTupleLength(path, 3, values.length())
_ => decode_type_error(path, "tuple", value)
}
}
///|
pub impl[A : ToRon, B : ToRon, C : ToRon, D : ToRon] ToRon for (A, B, C, D) with fn to_ron(
self,
options,
) {
Tuple([
ToRon::to_ron(self.0, options),
ToRon::to_ron(self.1, options),
ToRon::to_ron(self.2, options),
ToRon::to_ron(self.3, options),
])
}
///|
pub impl[A : FromRon, B : FromRon, C : FromRon, D : FromRon] FromRon for (
A,
B,
C,
D,
) with fn from_ron(value, path, options) {
match value {
Tuple(values) if values.length() == 4 =>
(
FromRon::from_ron(values[0], path.add_index(0), options),
FromRon::from_ron(values[1], path.add_index(1), options),
FromRon::from_ron(values[2], path.add_index(2), options),
FromRon::from_ron(values[3], path.add_index(3), options),
)
Tuple(values) => raise UnexpectedTupleLength(path, 4, values.length())
_ => decode_type_error(path, "tuple", value)
}
}
///|
pub impl[A : ToRon, B : ToRon, C : ToRon, D : ToRon, E : ToRon] ToRon for (
A,
B,
C,
D,
E,
) with fn to_ron(self, options) {
Tuple([
ToRon::to_ron(self.0, options),
ToRon::to_ron(self.1, options),
ToRon::to_ron(self.2, options),
ToRon::to_ron(self.3, options),
ToRon::to_ron(self.4, options),
])
}
///|
pub impl[A : FromRon, B : FromRon, C : FromRon, D : FromRon, E : FromRon] FromRon for (
A,
B,
C,
D,
E,
) with fn from_ron(value, path, options) {
match value {
Tuple(values) if values.length() == 5 =>
(
FromRon::from_ron(values[0], path.add_index(0), options),
FromRon::from_ron(values[1], path.add_index(1), options),
FromRon::from_ron(values[2], path.add_index(2), options),
FromRon::from_ron(values[3], path.add_index(3), options),
FromRon::from_ron(values[4], path.add_index(4), options),
)
Tuple(values) => raise UnexpectedTupleLength(path, 5, values.length())
_ => decode_type_error(path, "tuple", value)
}
}
///|
pub impl[A : ToRon, B : ToRon, C : ToRon, D : ToRon, E : ToRon, F : ToRon] ToRon for (
A,
B,
C,
D,
E,
F,
) with fn to_ron(self, options) {
Tuple([
ToRon::to_ron(self.0, options),
ToRon::to_ron(self.1, options),
ToRon::to_ron(self.2, options),
ToRon::to_ron(self.3, options),
ToRon::to_ron(self.4, options),
ToRon::to_ron(self.5, options),
])
}
///|
pub impl[
A : FromRon,
B : FromRon,
C : FromRon,
D : FromRon,
E : FromRon,
F : FromRon,
] FromRon for (A, B, C, D, E, F) with fn from_ron(value, path, options) {
match value {
Tuple(values) if values.length() == 6 =>
(
FromRon::from_ron(values[0], path.add_index(0), options),
FromRon::from_ron(values[1], path.add_index(1), options),
FromRon::from_ron(values[2], path.add_index(2), options),
FromRon::from_ron(values[3], path.add_index(3), options),
FromRon::from_ron(values[4], path.add_index(4), options),
FromRon::from_ron(values[5], path.add_index(5), options),
)
Tuple(values) => raise UnexpectedTupleLength(path, 6, values.length())
_ => decode_type_error(path, "tuple", value)
}
}
///|
pub impl[
A : ToRon,
B : ToRon,
C : ToRon,
D : ToRon,
E : ToRon,
F : ToRon,
G : ToRon,
] ToRon for (A, B, C, D, E, F, G) with fn to_ron(self, options) {
Tuple([
ToRon::to_ron(self.0, options),
ToRon::to_ron(self.1, options),
ToRon::to_ron(self.2, options),
ToRon::to_ron(self.3, options),
ToRon::to_ron(self.4, options),
ToRon::to_ron(self.5, options),
ToRon::to_ron(self.6, options),
])
}
///|
pub impl[
A : FromRon,
B : FromRon,
C : FromRon,
D : FromRon,
E : FromRon,
F : FromRon,
G : FromRon,
] FromRon for (A, B, C, D, E, F, G) with fn from_ron(value, path, options) {
match value {
Tuple(values) if values.length() == 7 =>
(
FromRon::from_ron(values[0], path.add_index(0), options),
FromRon::from_ron(values[1], path.add_index(1), options),
FromRon::from_ron(values[2], path.add_index(2), options),
FromRon::from_ron(values[3], path.add_index(3), options),
FromRon::from_ron(values[4], path.add_index(4), options),
FromRon::from_ron(values[5], path.add_index(5), options),
FromRon::from_ron(values[6], path.add_index(6), options),
)
Tuple(values) => raise UnexpectedTupleLength(path, 7, values.length())
_ => decode_type_error(path, "tuple", value)
}
}
///|
pub impl[
A : ToRon,
B : ToRon,
C : ToRon,
D : ToRon,
E : ToRon,
F : ToRon,
G : ToRon,
H : ToRon,
] ToRon for (A, B, C, D, E, F, G, H) with fn to_ron(self, options) {
Tuple([
ToRon::to_ron(self.0, options),
ToRon::to_ron(self.1, options),
ToRon::to_ron(self.2, options),
ToRon::to_ron(self.3, options),
ToRon::to_ron(self.4, options),
ToRon::to_ron(self.5, options),
ToRon::to_ron(self.6, options),
ToRon::to_ron(self.7, options),
])
}
///|
pub impl[
A : FromRon,
B : FromRon,
C : FromRon,
D : FromRon,
E : FromRon,
F : FromRon,
G : FromRon,
H : FromRon,
] FromRon for (A, B, C, D, E, F, G, H) with fn from_ron(value, path, options) {
match value {
Tuple(values) if values.length() == 8 =>
(
FromRon::from_ron(values[0], path.add_index(0), options),
FromRon::from_ron(values[1], path.add_index(1), options),
FromRon::from_ron(values[2], path.add_index(2), options),
FromRon::from_ron(values[3], path.add_index(3), options),
FromRon::from_ron(values[4], path.add_index(4), options),
FromRon::from_ron(values[5], path.add_index(5), options),
FromRon::from_ron(values[6], path.add_index(6), options),
FromRon::from_ron(values[7], path.add_index(7), options),
)
Tuple(values) => raise UnexpectedTupleLength(path, 8, values.length())
_ => decode_type_error(path, "tuple", value)
}
}