use std::collections::BTreeMap;
use super::{v1, *};
impl From<v1::StandardLibrary> for StandardLibrary {
fn from(mut v1: v1::StandardLibrary) -> Self {
let mut standard_library = StandardLibrary::default();
if let Some(meta) = v1.meta.take() {
standard_library.base = meta.base;
standard_library.name = meta.name;
if let Some(v1_structs) = meta.structs {
for (name, children) in v1_structs {
let mut struct_fields = BTreeMap::new();
for (name, v1_struct_field) in children {
struct_fields.extend(unpack_v1_field(name, v1_struct_field));
}
standard_library.structs.insert(name, struct_fields);
}
}
}
let mut globals = BTreeMap::new();
for (name, v1_global) in v1.globals {
globals.extend(unpack_v1_field(name, v1_global));
}
standard_library.globals = globals;
standard_library
}
}
impl From<v1::Argument> for Argument {
fn from(v1_argument: v1::Argument) -> Self {
Argument {
required: v1_argument.required.into(),
argument_type: v1_argument.argument_type.into(),
observes: Observes::ReadWrite,
deprecated: None,
}
}
}
impl From<v1::ArgumentType> for ArgumentType {
fn from(v1_argument_type: v1::ArgumentType) -> Self {
match v1_argument_type {
v1::ArgumentType::Any => ArgumentType::Any,
v1::ArgumentType::Bool => ArgumentType::Bool,
v1::ArgumentType::Constant(constants) => ArgumentType::Constant(constants),
v1::ArgumentType::Display(message) => ArgumentType::Display(message),
v1::ArgumentType::Function => ArgumentType::Function,
v1::ArgumentType::Nil => ArgumentType::Nil,
v1::ArgumentType::Number => ArgumentType::Number,
v1::ArgumentType::String => ArgumentType::String,
v1::ArgumentType::Table => ArgumentType::Table,
v1::ArgumentType::Vararg => ArgumentType::Vararg,
}
}
}
fn unpack_v1_field(name: String, v1_field: v1::Field) -> BTreeMap<String, Field> {
let mut upgraded_fields = BTreeMap::new();
let mut v1_fields = vec![(name, v1_field)];
while let Some((name, field)) = v1_fields.pop() {
match field {
v1::Field::Any => {
upgraded_fields.insert(name, Field::from_field_kind(FieldKind::Any));
}
v1::Field::Complex { function, table } => {
for (child_name, child_field) in table {
v1_fields.push((format!("{name}.{child_name}").to_owned(), child_field));
}
if let Some(function) = function {
upgraded_fields.insert(
name,
Field::from_field_kind(FieldKind::Function(FunctionBehavior {
arguments: function.arguments.into_iter().map(Into::into).collect(),
method: function.method,
must_use: false,
})),
);
}
}
v1::Field::Property { writable } => {
upgraded_fields.insert(
name,
Field::from_field_kind(FieldKind::Property(writable.into())),
);
}
v1::Field::Struct(struct_name) => {
upgraded_fields
.insert(name, Field::from_field_kind(FieldKind::Struct(struct_name)));
}
v1::Field::Removed => {
upgraded_fields.insert(name, Field::from_field_kind(FieldKind::Removed));
}
}
}
upgraded_fields
}
impl From<Option<v1::Writable>> for PropertyWritability {
fn from(v1_writable: Option<v1::Writable>) -> Self {
match v1_writable {
Some(v1::Writable::Full) => PropertyWritability::FullWrite,
Some(v1::Writable::NewFields) => PropertyWritability::NewFields,
Some(v1::Writable::Overridden) => PropertyWritability::OverrideFields,
None => PropertyWritability::ReadOnly,
}
}
}
impl From<v1::Required> for Required {
fn from(v1_required: v1::Required) -> Self {
match v1_required {
v1::Required::NotRequired => Required::NotRequired,
v1::Required::Required(message) => Required::Required(message),
}
}
}