diff --git a/packages/lib-roblox/src/instance/data_model.rs b/packages/lib-roblox/src/instance/data_model.rs index e057349..7f83be0 100644 --- a/packages/lib-roblox/src/instance/data_model.rs +++ b/packages/lib-roblox/src/instance/data_model.rs @@ -1,22 +1,58 @@ use mlua::prelude::*; -use crate::shared::classes::add_class_restricted_method; +use crate::shared::{classes::add_class_restricted_method, instance::class_is_a_service}; use super::Instance; pub const CLASS_NAME: &str = "DataModel"; pub fn add_methods<'lua, M: LuaUserDataMethods<'lua, Instance>>(methods: &mut M) { - add_class_restricted_method( - methods, - CLASS_NAME, - "GetService", - |_, _, _service_name: String| Ok(()), - ); - add_class_restricted_method( - methods, - CLASS_NAME, - "FindService", - |_, _, _service_name: String| Ok(()), - ); + add_class_restricted_method(methods, CLASS_NAME, "GetService", data_model_get_service); + add_class_restricted_method(methods, CLASS_NAME, "FindService", data_model_find_service); +} + +/** + Gets or creates a service for this DataModel. + + ### See Also + * [`GetService`](https://create.roblox.com/docs/reference/engine/classes/ServiceProvider#GetService) + on the Roblox Developer Hub +*/ +fn data_model_get_service(_: &Lua, this: &Instance, service_name: String) -> LuaResult { + if matches!(class_is_a_service(&service_name), None | Some(false)) { + Err(LuaError::RuntimeError(format!( + "'{}' is not a valid service name", + service_name + ))) + } else if let Some(service) = this.find_child(|child| child.class == service_name) { + Ok(service) + } else { + let service = Instance::new_orphaned(service_name); + service.set_parent(Some(this.clone())); + Ok(service) + } +} + +/** + Gets a service for this DataModel, if it exists. + + ### See Also + * [`FindService`](https://create.roblox.com/docs/reference/engine/classes/ServiceProvider#FindService) + on the Roblox Developer Hub +*/ +fn data_model_find_service( + _: &Lua, + this: &Instance, + service_name: String, +) -> LuaResult> { + if matches!(class_is_a_service(&service_name), None | Some(false)) { + Err(LuaError::RuntimeError(format!( + "'{}' is not a valid service name", + service_name + ))) + } else if let Some(service) = this.find_child(|child| child.class == service_name) { + Ok(Some(service)) + } else { + Ok(None) + } } diff --git a/packages/lib-roblox/src/instance/mod.rs b/packages/lib-roblox/src/instance/mod.rs index 2908cfc..dd30519 100644 --- a/packages/lib-roblox/src/instance/mod.rs +++ b/packages/lib-roblox/src/instance/mod.rs @@ -589,11 +589,16 @@ impl Instance { datatype_table.set( "new", lua.create_function(|lua, class_name: String| { - if class_exists(&class_name) { + if class_name == data_model::CLASS_NAME { + Err(LuaError::RuntimeError(format!( + "Failed to create Instance - '{}' class is restricted", + class_name + ))) + } else if class_exists(&class_name) { Instance::new_orphaned(class_name).to_lua(lua) } else { Err(LuaError::RuntimeError(format!( - "'{}' is not a valid class name", + "Failed to create Instance - '{}' is not a valid class name", class_name ))) }