Skip to main content

yog_script_analyze/
yog.rs

1//! Yog's surface as compiled code writes it (`yog-event`'s Java records,
2//! `dev.yog.bus`): a service's record called, an event's listened to, a
3//! payload's fields read.
4
5use yog_event::java;
6
7use crate::typeck::surface::SURFACE;
8
9/// A Yog method's call in Java.
10pub struct Service {
11    /// Its record, in full (`dev.yog.bus.YogServices.Chat.Broadcast`).
12    pub record: String,
13    /// It's a handle's (`player.Teleport(…)`): the handle is the record's
14    /// first field.
15    pub on_handle: bool,
16}
17
18/// Group (or handle) `group`'s method `method`.
19pub fn service(group: &str, method: &str) -> Option<Service> {
20    let m = SURFACE.groups.get(group)?.methods.get(method)?.first()?;
21    Some(Service {
22        record: format!(
23            "{}.{}.{}",
24            java::PACKAGE,
25            java::SERVICES,
26            java::record_path(m.domain, method)
27        ),
28        on_handle: is_handle(group),
29    })
30}
31
32/// Group `group`'s event `name`'s record, in full (`…YogEvents.Block.Break`).
33pub fn event(group: &str, name: &str) -> Option<String> {
34    let plane = SURFACE.groups.get(group)?.planes.get(name)?;
35    Some(format!(
36        "{}.{}.{}",
37        java::PACKAGE,
38        java::EVENTS,
39        java::record_path(plane, name)
40    ))
41}
42
43/// A payload type's Java class: an event's arguments' record, a struct's.
44pub fn data(name: &str) -> Option<String> {
45    if let Some((plane, event)) = SURFACE.args_planes.get(name) {
46        return Some(format!(
47            "{}.{}.{}",
48            java::PACKAGE,
49            java::EVENTS,
50            java::record_path(plane, event)
51        ));
52    }
53    let s = SURFACE.structs.get(name)?;
54    Some(format!("{}.{}.{}", java::PACKAGE, java::TYPES, s.name))
55}
56
57/// A payload field written `name` in a source (`PlayerName`): its Java
58/// accessor's name (`playerName`).
59pub fn field(name: &str) -> String {
60    java::field(&yog_codegen::snake(name))
61}
62
63/// Whether `name` is a handle (`Player`, `Entity`, `World`): in Java, its
64/// subject (a string).
65pub fn is_handle(name: &str) -> bool {
66    yog_event::SUBJECTS.iter().any(|(_, h)| *h == name)
67}
68
69/// The world's handle's name (`World`): its type's own.
70pub fn world() -> &'static str {
71    handle_name::<yog_event::World>()
72}
73
74/// The player's handle's name (`Player`): its type's own.
75pub fn player() -> &'static str {
76    handle_name::<yog_event::Player>()
77}
78
79/// Handle type `T`'s name, as Yog Script names it: its Rust type's own.
80fn handle_name<T>() -> &'static str {
81    let full = std::any::type_name::<T>();
82    full.rsplit(yog_script_ids::rust::PATH_SEP)
83        .next()
84        .unwrap_or(full)
85}