initial commit
This commit is contained in:
commit
7e3350739a
9 changed files with 5411 additions and 0 deletions
13
.cargo/config.toml
Normal file
13
.cargo/config.toml
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
[target.x86_64-unknown-linux-gnu]
|
||||||
|
linker = "clang"
|
||||||
|
rustflags = ["-C", "link-arg=-fuse-ld=/usr/bin/mold", "-Zshare-generics=y"]
|
||||||
|
|
||||||
|
[unstable]
|
||||||
|
codegen-backend = true
|
||||||
|
|
||||||
|
[profile.dev]
|
||||||
|
codegen-backend = "cranelift"
|
||||||
|
|
||||||
|
[profile.dev.package."*"]
|
||||||
|
codegen-backend = "llvm"
|
||||||
|
|
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
target/
|
||||||
|
|
4737
Cargo.lock
generated
Normal file
4737
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load diff
18
Cargo.toml
Normal file
18
Cargo.toml
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
[package]
|
||||||
|
name = "bevy-blender"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
name = "bevy_blender"
|
||||||
|
path = "src/lib.rs"
|
||||||
|
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
bevy = "0.15.0"
|
||||||
|
ron = "0.8.1"
|
||||||
|
serde = { version = "1.0.215", features = ["derive"] }
|
||||||
|
serde_json = "1.0.133"
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
bevy = { version = "0.15.0", features = ["dynamic_linking"] }
|
BIN
assets/gltf_extras.glb
Normal file
BIN
assets/gltf_extras.glb
Normal file
Binary file not shown.
3
rust-toolchain.toml
Normal file
3
rust-toolchain.toml
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
[toolchain]
|
||||||
|
channel = "nightly"
|
||||||
|
|
50
src/lib.rs
Normal file
50
src/lib.rs
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
use bevy::prelude::*;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
use self::registry::CreateRegistryPlugin;
|
||||||
|
|
||||||
|
mod registry;
|
||||||
|
|
||||||
|
#[derive(Debug, Resource)]
|
||||||
|
pub struct BevyBlenderConfig {
|
||||||
|
pub create_registry: bool,
|
||||||
|
pub registry_path: PathBuf,
|
||||||
|
pub type_filter: SceneFilter,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&BevyBlenderPlugin> for BevyBlenderConfig {
|
||||||
|
fn from(value: &BevyBlenderPlugin) -> Self {
|
||||||
|
Self {
|
||||||
|
create_registry: value.create_registry,
|
||||||
|
registry_path: value.registry_path.clone(),
|
||||||
|
type_filter: value.type_filter.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct BevyBlenderPlugin {
|
||||||
|
create_registry: bool,
|
||||||
|
registry_path: PathBuf,
|
||||||
|
type_filter: SceneFilter,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for BevyBlenderPlugin {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
create_registry: true,
|
||||||
|
registry_path: "registry.json".into(),
|
||||||
|
type_filter: SceneFilter::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Plugin for BevyBlenderPlugin {
|
||||||
|
fn build(&self, app: &mut bevy::prelude::App) {
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
if self.create_registry {
|
||||||
|
app.add_plugins(CreateRegistryPlugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
app.insert_resource(BevyBlenderConfig::from(self));
|
||||||
|
}
|
||||||
|
}
|
159
src/main.rs
Normal file
159
src/main.rs
Normal file
|
@ -0,0 +1,159 @@
|
||||||
|
mod registry;
|
||||||
|
|
||||||
|
use bevy::{
|
||||||
|
gltf::{GltfExtras, GltfMaterialExtras, GltfMeshExtras, GltfSceneExtras},
|
||||||
|
prelude::*,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub use bevy_blender::{BevyBlenderConfig, BevyBlenderPlugin};
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
App::new()
|
||||||
|
.add_plugins(DefaultPlugins)
|
||||||
|
.add_plugins(BevyBlenderPlugin::default())
|
||||||
|
.add_systems(Startup, setup)
|
||||||
|
.add_systems(Update, read_gltfs)
|
||||||
|
.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
//#[derive(Deserialize, Debug, Serialize)]
|
||||||
|
//struct NestedStruct(String, usize);
|
||||||
|
//
|
||||||
|
//#[derive(Deserialize, Debug, Serialize)]
|
||||||
|
//struct TestStruct {
|
||||||
|
// pub number: usize,
|
||||||
|
// pub pair: (char, i32),
|
||||||
|
// nested: NestedStruct,
|
||||||
|
//}
|
||||||
|
|
||||||
|
fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
|
||||||
|
//let cfg = ron::ser::PrettyConfig::new().struct_names(true);
|
||||||
|
//let r = ron::ser::to_string_pretty(
|
||||||
|
// &TestStruct {
|
||||||
|
// number: 11,
|
||||||
|
// pair: ('r', 69),
|
||||||
|
// nested: NestedStruct("aeraaraaa".to_string(), 44),
|
||||||
|
// },
|
||||||
|
// cfg,
|
||||||
|
//)
|
||||||
|
//.unwrap();
|
||||||
|
|
||||||
|
//let awera: TestStruct = ron::de::from_str(&r).unwrap();
|
||||||
|
commands.spawn((
|
||||||
|
Camera3d::default(),
|
||||||
|
Transform::from_xyz(2.0, 2.0, 2.0).looking_at(Vec3::ZERO, Vec3::Y),
|
||||||
|
));
|
||||||
|
|
||||||
|
commands.spawn(DirectionalLight {
|
||||||
|
shadows_enabled: true,
|
||||||
|
..default()
|
||||||
|
});
|
||||||
|
|
||||||
|
commands.spawn(SceneRoot(
|
||||||
|
asset_server.load(GltfAssetLabel::Scene(0).from_asset("gltf_extras.glb")),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_gltfs(
|
||||||
|
mut commands: Commands,
|
||||||
|
extras_q: Query<(Entity, &GltfExtras), Added<GltfExtras>>,
|
||||||
|
scene_extras_q: Query<(Entity, &GltfSceneExtras), Added<GltfSceneExtras>>,
|
||||||
|
mesh_extras_q: Query<(Entity, &GltfMeshExtras), Added<GltfMeshExtras>>,
|
||||||
|
material_extras_q: Query<(Entity, &GltfMaterialExtras), Added<GltfMaterialExtras>>,
|
||||||
|
) {
|
||||||
|
for (entity, extras) in extras_q.iter() {
|
||||||
|
println!("{:?}", extras);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (entity, extras) in scene_extras_q.iter() {
|
||||||
|
println!("{:?}", extras);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (entity, extras) in mesh_extras_q.iter() {
|
||||||
|
println!("{:?}", extras);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (entity, extras) in material_extras_q.iter() {
|
||||||
|
println!("{:?}", extras);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//#[derive(Component)]
|
||||||
|
//struct ExampleDisplay;
|
||||||
|
//
|
||||||
|
//fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
|
||||||
|
// commands.spawn((
|
||||||
|
// Camera3d::default(),
|
||||||
|
// Transform::from_xyz(2.0, 2.0, 2.0).looking_at(Vec3::ZERO, Vec3::Y),
|
||||||
|
// ));
|
||||||
|
//
|
||||||
|
// commands.spawn(DirectionalLight {
|
||||||
|
// shadows_enabled: true,
|
||||||
|
// ..default()
|
||||||
|
// });
|
||||||
|
//
|
||||||
|
// // a barebones scene containing one of each gltf_extra type
|
||||||
|
// commands.spawn(SceneRoot(
|
||||||
|
// asset_server.load(GltfAssetLabel::Scene(0).from_asset("gltf_extras.glb")),
|
||||||
|
// ));
|
||||||
|
//
|
||||||
|
// // a place to display the extras on screen
|
||||||
|
// commands.spawn((
|
||||||
|
// Text::default(),
|
||||||
|
// TextFont {
|
||||||
|
// font_size: 15.,
|
||||||
|
// ..default()
|
||||||
|
// },
|
||||||
|
// Node {
|
||||||
|
// position_type: PositionType::Absolute,
|
||||||
|
// top: Val::Px(12.0),
|
||||||
|
// left: Val::Px(12.0),
|
||||||
|
// ..default()
|
||||||
|
// },
|
||||||
|
// ExampleDisplay,
|
||||||
|
// ));
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//fn check_for_gltf_extras(
|
||||||
|
// gltf_extras_per_entity: Query<
|
||||||
|
// (
|
||||||
|
// Entity,
|
||||||
|
// Option<&Name>,
|
||||||
|
// Option<&GltfSceneExtras>,
|
||||||
|
// Option<&GltfExtras>,
|
||||||
|
// Option<&GltfMeshExtras>,
|
||||||
|
// Option<&GltfMaterialExtras>,
|
||||||
|
// ),
|
||||||
|
// Added<Mesh3d>,
|
||||||
|
// >,
|
||||||
|
// mut display: Single<&mut Text, With<ExampleDisplay>>,
|
||||||
|
//) {
|
||||||
|
// let mut gltf_extra_infos_lines: Vec<String> = vec![];
|
||||||
|
//
|
||||||
|
// for (id, name, scene_extras, extras, mesh_extras, material_extras) in
|
||||||
|
// gltf_extras_per_entity.iter()
|
||||||
|
// {
|
||||||
|
// if scene_extras.is_some()
|
||||||
|
// || extras.is_some()
|
||||||
|
// || mesh_extras.is_some()
|
||||||
|
// || material_extras.is_some()
|
||||||
|
// {
|
||||||
|
// let formatted_extras = format!(
|
||||||
|
// "Extras per entity {} ('Name: {}'):
|
||||||
|
// - scene extras: {:?}
|
||||||
|
// - primitive extras: {:?}
|
||||||
|
// - mesh extras: {:?}
|
||||||
|
// - material extras: {:?}
|
||||||
|
// ",
|
||||||
|
// id,
|
||||||
|
// name.unwrap_or(&Name::default()),
|
||||||
|
// scene_extras,
|
||||||
|
// extras,
|
||||||
|
// mesh_extras,
|
||||||
|
// material_extras
|
||||||
|
// );
|
||||||
|
// gltf_extra_infos_lines.push(formatted_extras);
|
||||||
|
// }
|
||||||
|
// display.0 = gltf_extra_infos_lines.join("\n");
|
||||||
|
// }
|
||||||
|
//}
|
429
src/registry.rs
Normal file
429
src/registry.rs
Normal file
|
@ -0,0 +1,429 @@
|
||||||
|
use bevy::prelude::*;
|
||||||
|
use bevy::reflect::{
|
||||||
|
ArrayInfo, EnumInfo, ListInfo, MapInfo, NamedField, OpaqueInfo, SetInfo, StructInfo,
|
||||||
|
StructVariantInfo, TupleInfo, TupleStructInfo, TupleVariantInfo, Type, TypeInfo,
|
||||||
|
TypeRegistration, UnitVariantInfo, UnnamedField, VariantInfo,
|
||||||
|
};
|
||||||
|
use bevy::utils::HashMap;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::BevyBlenderConfig;
|
||||||
|
|
||||||
|
pub(crate) struct CreateRegistryPlugin;
|
||||||
|
|
||||||
|
impl Plugin for CreateRegistryPlugin {
|
||||||
|
fn build(&self, app: &mut bevy::prelude::App) {
|
||||||
|
app.add_systems(Startup, create_registry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_registry(config: Res<BevyBlenderConfig>, type_registry: Res<AppTypeRegistry>) {
|
||||||
|
let type_registry = type_registry.read();
|
||||||
|
let filter = &config.type_filter;
|
||||||
|
let types: Vec<RegistryEntry> = type_registry
|
||||||
|
.iter()
|
||||||
|
.filter(|t| filter.is_allowed_by_id(t.type_id()))
|
||||||
|
.map(RegistryEntry::from)
|
||||||
|
.collect();
|
||||||
|
println!("{types:?}");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
enum SchemaType {
|
||||||
|
Array,
|
||||||
|
Object,
|
||||||
|
Value(ValueVariant),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&NativeType> for SchemaType {
|
||||||
|
fn from(value: &NativeType) -> Self {
|
||||||
|
match value {
|
||||||
|
NativeType::Enum { .. } => SchemaType::Object,
|
||||||
|
NativeType::List { .. } => SchemaType::Array,
|
||||||
|
NativeType::Map { .. } => SchemaType::Object,
|
||||||
|
NativeType::Opaque(value) => SchemaType::Value(ValueVariant::from(value)),
|
||||||
|
NativeType::Set { .. } => SchemaType::Object,
|
||||||
|
NativeType::Tuple { .. } => SchemaType::Array,
|
||||||
|
NativeType::Struct { .. } => SchemaType::Object,
|
||||||
|
NativeType::Unit => SchemaType::Object,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
enum ValueVariant {
|
||||||
|
Boolean,
|
||||||
|
UnsignedInteger,
|
||||||
|
Integer,
|
||||||
|
Float,
|
||||||
|
String,
|
||||||
|
Object,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&OpaqueVariant> for ValueVariant {
|
||||||
|
fn from(value: &OpaqueVariant) -> Self {
|
||||||
|
match value {
|
||||||
|
OpaqueVariant::Boolean => Self::Boolean,
|
||||||
|
OpaqueVariant::Char => Self::String,
|
||||||
|
OpaqueVariant::Integer(IntSign::Unsigned, _) => Self::UnsignedInteger,
|
||||||
|
OpaqueVariant::Integer(IntSign::Signed, _) => Self::Integer,
|
||||||
|
OpaqueVariant::Float => Self::Float,
|
||||||
|
OpaqueVariant::String => Self::String,
|
||||||
|
OpaqueVariant::Struct => Self::Object,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
struct TypeRef {
|
||||||
|
#[serde(rename = "$ref")]
|
||||||
|
ref_type: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TypeRef {
|
||||||
|
pub fn new<T: std::fmt::Display>(value: T) -> Self {
|
||||||
|
Self {
|
||||||
|
ref_type: format!("#/defs/{value}"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
struct FieldType {
|
||||||
|
#[serde(rename = "type")]
|
||||||
|
type_ref: TypeRef,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FieldType {
|
||||||
|
pub fn new<T: std::fmt::Display>(value: T) -> Self {
|
||||||
|
Self {
|
||||||
|
type_ref: TypeRef::new(value),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Type> for FieldType {
|
||||||
|
fn from(value: Type) -> Self {
|
||||||
|
Self::new(value.path())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&Type> for FieldType {
|
||||||
|
fn from(value: &Type) -> Self {
|
||||||
|
Self::new(value.path())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&NamedField> for FieldType {
|
||||||
|
fn from(value: &NamedField) -> Self {
|
||||||
|
value.ty().into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&UnnamedField> for FieldType {
|
||||||
|
fn from(value: &UnnamedField) -> Self {
|
||||||
|
value.ty().into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
enum NativeType {
|
||||||
|
Enum {
|
||||||
|
one_of: Vec<NativeType>,
|
||||||
|
},
|
||||||
|
List {
|
||||||
|
items: FieldType,
|
||||||
|
variant: ListVariant,
|
||||||
|
},
|
||||||
|
Map {
|
||||||
|
key_type: FieldType,
|
||||||
|
value_type: FieldType,
|
||||||
|
},
|
||||||
|
Opaque(OpaqueVariant),
|
||||||
|
Set {
|
||||||
|
value_type: FieldType,
|
||||||
|
},
|
||||||
|
Tuple {
|
||||||
|
prefix_items: Vec<FieldType>,
|
||||||
|
variant: TupleVariant,
|
||||||
|
},
|
||||||
|
Struct {
|
||||||
|
properties: HashMap<String, FieldType>,
|
||||||
|
additional_properties: bool,
|
||||||
|
required: Vec<String>,
|
||||||
|
},
|
||||||
|
Unit,
|
||||||
|
}
|
||||||
|
|
||||||
|
enum StructType<'a> {
|
||||||
|
Struct(&'a StructInfo),
|
||||||
|
StructVariant(&'a StructVariantInfo),
|
||||||
|
}
|
||||||
|
|
||||||
|
enum TupleType<'a> {
|
||||||
|
Tuple(&'a TupleInfo),
|
||||||
|
TupleVariant(&'a TupleVariantInfo),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NativeType {
|
||||||
|
fn from_struct(value: StructType) -> Self {
|
||||||
|
let iter = match value {
|
||||||
|
StructType::Struct(info) => info.iter(),
|
||||||
|
StructType::StructVariant(info) => info.iter(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let properties = iter
|
||||||
|
.as_ref()
|
||||||
|
.into_iter()
|
||||||
|
.map(|field| (field.name().to_string(), field.into()))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let option_path = "core::option::Option";
|
||||||
|
let required = iter
|
||||||
|
.filter(|field| !field.type_path().starts_with(&option_path))
|
||||||
|
.map(|field| field.name().to_string())
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
Self::Struct {
|
||||||
|
properties,
|
||||||
|
additional_properties: false,
|
||||||
|
required,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn from_tuple(value: TupleType) -> Self {
|
||||||
|
let iter = match value {
|
||||||
|
TupleType::Tuple(info) => info.iter(),
|
||||||
|
TupleType::TupleVariant(info) => info.iter(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let prefix_items = iter.map(FieldType::from).collect();
|
||||||
|
|
||||||
|
Self::Tuple {
|
||||||
|
prefix_items,
|
||||||
|
variant: TupleVariant::Tuple,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&VariantInfo> for NativeType {
|
||||||
|
fn from(value: &VariantInfo) -> Self {
|
||||||
|
match value {
|
||||||
|
VariantInfo::Struct(info) => NativeType::from(info),
|
||||||
|
VariantInfo::Tuple(info) => NativeType::from(info),
|
||||||
|
VariantInfo::Unit(info) => NativeType::from(info),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&StructVariantInfo> for NativeType {
|
||||||
|
fn from(value: &StructVariantInfo) -> Self {
|
||||||
|
Self::from_struct(StructType::StructVariant(value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&TupleVariantInfo> for NativeType {
|
||||||
|
fn from(value: &TupleVariantInfo) -> Self {
|
||||||
|
Self::from_tuple(TupleType::TupleVariant(value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&UnitVariantInfo> for NativeType {
|
||||||
|
fn from(_value: &UnitVariantInfo) -> Self {
|
||||||
|
Self::Unit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&TypeRegistration> for NativeType {
|
||||||
|
fn from(value: &TypeRegistration) -> Self {
|
||||||
|
value.type_info().into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&TypeInfo> for NativeType {
|
||||||
|
fn from(value: &TypeInfo) -> Self {
|
||||||
|
match value {
|
||||||
|
TypeInfo::Struct(info) => NativeType::from(info),
|
||||||
|
TypeInfo::TupleStruct(info) => NativeType::from(info),
|
||||||
|
TypeInfo::Tuple(info) => NativeType::from(info),
|
||||||
|
TypeInfo::List(info) => NativeType::from(info),
|
||||||
|
TypeInfo::Array(info) => NativeType::from(info),
|
||||||
|
TypeInfo::Map(info) => NativeType::from(info),
|
||||||
|
TypeInfo::Set(info) => NativeType::from(info),
|
||||||
|
TypeInfo::Enum(info) => NativeType::from(info),
|
||||||
|
TypeInfo::Opaque(info) => NativeType::from(info),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&ArrayInfo> for NativeType {
|
||||||
|
fn from(value: &ArrayInfo) -> Self {
|
||||||
|
Self::List {
|
||||||
|
items: value.item_ty().into(),
|
||||||
|
variant: ListVariant::Array,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&EnumInfo> for NativeType {
|
||||||
|
fn from(value: &EnumInfo) -> Self {
|
||||||
|
let one_of = value.iter().map(NativeType::from).collect();
|
||||||
|
|
||||||
|
Self::Enum { one_of }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&ListInfo> for NativeType {
|
||||||
|
fn from(value: &ListInfo) -> Self {
|
||||||
|
Self::List {
|
||||||
|
items: FieldType::new(value.item_ty().path()),
|
||||||
|
variant: ListVariant::List,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&MapInfo> for NativeType {
|
||||||
|
fn from(value: &MapInfo) -> Self {
|
||||||
|
Self::Map {
|
||||||
|
key_type: FieldType::new(value.key_ty().path()),
|
||||||
|
value_type: FieldType::new(value.value_ty().path()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&OpaqueInfo> for NativeType {
|
||||||
|
fn from(value: &OpaqueInfo) -> Self {
|
||||||
|
Self::Opaque(OpaqueVariant::from(value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&SetInfo> for NativeType {
|
||||||
|
fn from(value: &SetInfo) -> Self {
|
||||||
|
Self::Set {
|
||||||
|
value_type: value.value_ty().into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&StructInfo> for NativeType {
|
||||||
|
fn from(value: &StructInfo) -> Self {
|
||||||
|
Self::from_struct(StructType::Struct(value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&TupleInfo> for NativeType {
|
||||||
|
fn from(value: &TupleInfo) -> Self {
|
||||||
|
Self::from_tuple(TupleType::Tuple(value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&TupleStructInfo> for NativeType {
|
||||||
|
fn from(value: &TupleStructInfo) -> Self {
|
||||||
|
let prefix_items = value.iter().map(FieldType::from).collect();
|
||||||
|
Self::Tuple {
|
||||||
|
prefix_items,
|
||||||
|
variant: TupleVariant::TupleStruct,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
enum ListVariant {
|
||||||
|
Array,
|
||||||
|
List,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
enum TupleVariant {
|
||||||
|
Tuple,
|
||||||
|
TupleStruct,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
enum IntSign {
|
||||||
|
Signed,
|
||||||
|
Unsigned,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IntSign {
|
||||||
|
fn from_str<T: AsRef<str>>(value: T) -> Self {
|
||||||
|
if value.as_ref().starts_with('u') {
|
||||||
|
IntSign::Unsigned
|
||||||
|
} else {
|
||||||
|
IntSign::Signed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
enum IntSize {
|
||||||
|
Sized(u8),
|
||||||
|
PointerSized,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IntSize {
|
||||||
|
fn from_str<T: AsRef<str>>(value: T) -> Self {
|
||||||
|
let size = &value.as_ref()[1..];
|
||||||
|
if size == "size" {
|
||||||
|
Self::PointerSized
|
||||||
|
} else {
|
||||||
|
let size = u8::from_str_radix(size, 10).unwrap();
|
||||||
|
Self::Sized(size)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
enum OpaqueVariant {
|
||||||
|
Boolean,
|
||||||
|
Integer(IntSign, IntSize),
|
||||||
|
Float,
|
||||||
|
Char,
|
||||||
|
String,
|
||||||
|
Struct,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl OpaqueVariant {
|
||||||
|
fn int_from_str<T: AsRef<str>>(value: T) -> Self {
|
||||||
|
let sign = IntSign::from_str(&value);
|
||||||
|
let size = IntSize::from_str(&value);
|
||||||
|
|
||||||
|
Self::Integer(sign, size)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&OpaqueInfo> for OpaqueVariant {
|
||||||
|
fn from(value: &OpaqueInfo) -> Self {
|
||||||
|
match value.type_path() {
|
||||||
|
"bool" => Self::Boolean,
|
||||||
|
value @ ("u8" | "u16" | "u32" | "u64" | "u128" | "usize" | "i8" | "i16" | "i32"
|
||||||
|
| "i64" | "i128" | "isize") => Self::int_from_str(value),
|
||||||
|
"f32" | "f64" => Self::Float,
|
||||||
|
"char" | "str" | "alloc::string::String" => Self::String,
|
||||||
|
_ => Self::Struct,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
struct RegistryEntry {
|
||||||
|
#[serde(rename = "type")]
|
||||||
|
schema_type: SchemaType,
|
||||||
|
native_type: NativeType,
|
||||||
|
qualified_type_path: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&TypeRegistration> for RegistryEntry {
|
||||||
|
fn from(value: &TypeRegistration) -> Self {
|
||||||
|
let type_info = value.type_info();
|
||||||
|
let native_type = NativeType::from(type_info);
|
||||||
|
let schema_type = SchemaType::from(&native_type);
|
||||||
|
|
||||||
|
Self {
|
||||||
|
schema_type,
|
||||||
|
native_type,
|
||||||
|
qualified_type_path: type_info.type_path().to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue