use crate::proto::schema::WebotsNode;
use crate::proto::validation::{NodeSchema, SchemaField};
use crate::versions::r2025a::nodes::*;
pub(crate) fn get_builtin_schema(type_name: &str) -> Option<NodeSchema> {
type SchemaBuilder = fn() -> NodeSchema;
type BuiltinSchemaEntry = (&'static str, SchemaBuilder);
let schemas: [BuiltinSchemaEntry; 86] = [
("WorldInfo", || schema::<WorldInfo>()),
("Viewpoint", || schema::<Viewpoint>()),
("Group", || schema::<Group>()),
("Pose", || schema::<Pose>()),
("Transform", || schema::<Transform>()),
("Billboard", || schema::<Billboard>()),
("Shape", || schema::<Shape>()),
("Appearance", || schema::<Appearance>()),
("PBRAppearance", || schema::<PBRAppearance>()),
("Material", || schema::<Material>()),
("ImageTexture", || schema::<ImageTexture>()),
("TextureTransform", || schema::<TextureTransform>()),
("Box", || schema::<BoxNode>()),
("Sphere", || schema::<Sphere>()),
("Capsule", || schema::<Capsule>()),
("Cylinder", || schema::<Cylinder>()),
("Plane", || schema::<Plane>()),
("Cone", || schema::<Cone>()),
("ElevationGrid", || schema::<ElevationGrid>()),
("IndexedFaceSet", || schema::<IndexedFaceSet>()),
("IndexedLineSet", || schema::<IndexedLineSet>()),
("PointSet", || schema::<PointSet>()),
("Mesh", || schema::<Mesh>()),
("CadShape", || schema::<CadShape>()),
("Robot", || schema::<Robot>()),
("Solid", || schema::<Solid>()),
("Fluid", || schema::<Fluid>()),
("Accelerometer", || schema::<Accelerometer>()),
("Altimeter", || schema::<Altimeter>()),
("Camera", || schema::<Camera>()),
("Compass", || schema::<Compass>()),
("DistanceSensor", || schema::<DistanceSensor>()),
("GPS", || schema::<GPS>()),
("Gyro", || schema::<Gyro>()),
("InertialUnit", || schema::<InertialUnit>()),
("Lidar", || schema::<Lidar>()),
("LightSensor", || schema::<LightSensor>()),
("PositionSensor", || schema::<PositionSensor>()),
("Radar", || schema::<Radar>()),
("RangeFinder", || schema::<RangeFinder>()),
("TouchSensor", || schema::<TouchSensor>()),
("RotationalMotor", || schema::<RotationalMotor>()),
("LinearMotor", || schema::<LinearMotor>()),
("Brake", || schema::<Brake>()),
("Propeller", || schema::<Propeller>()),
("Muscle", || schema::<Muscle>()),
("HingeJoint", || schema::<HingeJoint>()),
("Hinge2Joint", || schema::<Hinge2Joint>()),
("BallJoint", || schema::<BallJoint>()),
("SliderJoint", || schema::<SliderJoint>()),
("JointParameters", || schema::<JointParameters>()),
("HingeJointParameters", || schema::<HingeJointParameters>()),
("BallJointParameters", || schema::<BallJointParameters>()),
("LED", || schema::<LED>()),
("Emitter", || schema::<Emitter>()),
("Receiver", || schema::<Receiver>()),
("Connector", || schema::<Connector>()),
("Display", || schema::<Display>()),
("Pen", || schema::<Pen>()),
("Speaker", || schema::<Speaker>()),
("Charger", || schema::<Charger>()),
("VacuumGripper", || schema::<VacuumGripper>()),
("Track", || schema::<Track>()),
("TrackWheel", || schema::<TrackWheel>()),
("Skin", || schema::<Skin>()),
("Background", || schema::<Background>()),
("Fog", || schema::<Fog>()),
("DirectionalLight", || schema::<DirectionalLight>()),
("PointLight", || schema::<PointLight>()),
("SpotLight", || schema::<SpotLight>()),
("Physics", || schema::<Physics>()),
("Damping", || schema::<Damping>()),
("ContactProperties", || schema::<ContactProperties>()),
("ImmersionProperties", || schema::<ImmersionProperties>()),
("SolidReference", || schema::<SolidReference>()),
("Color", || schema::<Color>()),
("Coordinate", || schema::<Coordinate>()),
("Normal", || schema::<Normal>()),
("TextureCoordinate", || schema::<TextureCoordinate>()),
("Slot", || schema::<Slot>()),
("Focus", || schema::<Focus>()),
("Lens", || schema::<Lens>()),
("LensFlare", || schema::<LensFlare>()),
("Recognition", || schema::<Recognition>()),
("Zoom", || schema::<Zoom>()),
("RectangleArena", || schema::<RectangleArena>()),
];
for (name, builder) in schemas {
if name == type_name {
return Some(builder());
}
}
None
}
fn schema<T: WebotsNode>() -> NodeSchema {
NodeSchema {
name: T::node_name(),
fields: T::all_fields()
.iter()
.map(|(name, field_type)| SchemaField {
name: to_webots_field_name(name),
field_type: field_type.clone(),
})
.collect(),
}
}
fn to_webots_field_name(name: &str) -> String {
if !name.contains('_') {
return name.to_string();
}
let mut output = String::with_capacity(name.len());
let mut capitalize_next = false;
for character in name.chars() {
if character == '_' {
capitalize_next = true;
continue;
}
if capitalize_next {
output.extend(character.to_uppercase());
capitalize_next = false;
} else {
output.push(character);
}
}
output
}