1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
mod entity;
mod guid;
mod parent;
mod transform;
use genco::fmt;
use genco::prelude::*;
use std::fs::File;

use bevy::ecs::world::EntityMut;
pub use entity::*;
pub use guid::*;
pub use parent::*;
pub use transform::*;
use unrust_proc_macro::generate_inbuilt;

generate_inbuilt!((UnityParent, UnityEntity, UnityGUID, UnityTransform));

pub fn write_csharp_inbuilt(path: &str) -> anyhow::Result<()> {
    let struct_layout = &csharp::import("System.Runtime.InteropServices", "StructLayout");
    let layout_kind = &csharp::import("System.Runtime.InteropServices", "LayoutKind");
    let unity_types = UNITY_TYPES;
    let unity_union = UNITY_UNION;
    let unity_count = UNITY_COUNT;
    let inbuilt_tokens = get_inbuilt_csharp_tokens();
    let output: csharp::Tokens = genco::prelude::quote! {
        namespace unrust.runtime
        {
            $(for n in inbuilt_tokens => $n)

            [$struct_layout($layout_kind.Sequential)]
            public struct UnityData
            {
                public UnityTypes ty;
                public UnityComponents value;
            }

            public enum UnityTypes : sbyte
            {
                $(unity_types)
            }

            [$struct_layout($layout_kind.Explicit)]
            public unsafe struct UnityComponents
            {
                public const int ComponentCount = $unity_count;

                $(unity_union)
            }

            [$struct_layout($layout_kind.Sequential)]
            public unsafe struct EntityData
            {
                public UnityEntity entity;
                public UnityData* data;
                public nuint len;
            }
        }
    };

    let fmt = fmt::Config::from_lang::<Csharp>().with_indentation(fmt::Indentation::Space(4));
    let config = csharp::Config::default();

    let file = File::create(path)?;
    let mut w = fmt::IoWriter::new(file);
    output.format_file(&mut w.as_formatter(&fmt), &config)?;

    Ok(())
}