lust/embed/
native_types.rs

1use crate::ast::{
2    EnumDef, EnumVariant, FieldOwnership, FunctionDef, FunctionParam, ImplBlock, Span, StructDef,
3    StructField, TraitBound, TraitDef, TraitMethod, Type, TypeKind, Visibility,
4};
5use crate::typechecker::{FunctionSignature, TypeChecker};
6use crate::vm::VM;
7use crate::Result;
8use hashbrown::HashMap;
9use std::collections::BTreeMap;
10
11/// Aggregates Lust type declarations that originate from Rust.
12#[derive(Clone, Default)]
13pub struct ExternRegistry {
14    structs: Vec<StructDef>,
15    enums: Vec<EnumDef>,
16    traits: Vec<TraitDef>,
17    impls: Vec<ImplBlock>,
18    functions: Vec<FunctionDef>,
19}
20
21impl ExternRegistry {
22    pub fn new() -> Self {
23        Self::default()
24    }
25
26    pub fn add_struct(&mut self, def: StructDef) -> &mut Self {
27        self.structs.push(def);
28        self
29    }
30
31    pub fn add_enum(&mut self, def: EnumDef) -> &mut Self {
32        self.enums.push(def);
33        self
34    }
35
36    pub fn add_trait(&mut self, def: TraitDef) -> &mut Self {
37        self.traits.push(def);
38        self
39    }
40
41    pub fn add_impl(&mut self, impl_block: ImplBlock) -> &mut Self {
42        self.impls.push(impl_block);
43        self
44    }
45
46    pub fn add_function(&mut self, func: FunctionDef) -> &mut Self {
47        self.functions.push(func);
48        self
49    }
50
51    pub fn extend(&mut self, other: &ExternRegistry) {
52        self.structs.extend(other.structs.iter().cloned());
53        self.enums.extend(other.enums.iter().cloned());
54        self.traits.extend(other.traits.iter().cloned());
55        self.impls.extend(other.impls.iter().cloned());
56        self.functions.extend(other.functions.iter().cloned());
57    }
58
59    pub fn register_with_typechecker(&self, checker: &mut TypeChecker) -> Result<()> {
60        for def in &self.structs {
61            checker.register_external_struct(def.clone())?;
62        }
63        for def in &self.enums {
64            checker.register_external_enum(def.clone())?;
65        }
66        for def in &self.traits {
67            checker.register_external_trait(def.clone())?;
68        }
69        for func in &self.functions {
70            checker.register_external_function(function_signature_for(func))?;
71        }
72        for impl_block in &self.impls {
73            checker.register_external_impl(impl_block.clone())?;
74        }
75        Ok(())
76    }
77
78    pub fn register_with_vm(&self, vm: &mut VM) {
79        self.register_struct_layouts(vm);
80        self.register_type_stubs(vm);
81    }
82
83    pub fn register_struct_layouts(&self, vm: &mut VM) {
84        let prefix = vm.export_prefix();
85        let mut struct_map: HashMap<String, StructDef> = HashMap::new();
86        for def in &self.structs {
87            let canonical = canonicalize_struct(def, prefix.as_deref());
88            struct_map.insert(canonical.name.clone(), canonical);
89        }
90        if !struct_map.is_empty() {
91            vm.register_structs(&struct_map);
92        }
93    }
94
95    pub fn register_type_stubs(&self, vm: &mut VM) {
96        if self.structs.is_empty()
97            && self.enums.is_empty()
98            && self.traits.is_empty()
99            && self.impls.is_empty()
100        {
101            return;
102        }
103        let prefix = vm.export_prefix();
104        vm.register_type_stubs(self.module_stubs_with_prefix(prefix.as_deref()));
105    }
106
107    pub fn module_stubs(&self) -> Vec<ModuleStub> {
108        self.module_stubs_with_prefix(None)
109    }
110
111    fn module_stubs_with_prefix(&self, prefix: Option<&str>) -> Vec<ModuleStub> {
112        let mut modules: BTreeMap<String, ModuleStub> = BTreeMap::new();
113        for def in &self.structs {
114            let canonical = canonicalize_struct(def, prefix);
115            if let Some((module, name)) = module_and_name(&canonical.name) {
116                let entry = modules.entry(module.clone()).or_insert_with(|| ModuleStub {
117                    module,
118                    ..ModuleStub::default()
119                });
120                entry.struct_defs.push(format_struct_def(name, &canonical));
121            }
122        }
123        for def in &self.enums {
124            let canonical = canonicalize_enum(def, prefix);
125            if let Some((module, name)) = module_and_name(&canonical.name) {
126                let entry = modules.entry(module.clone()).or_insert_with(|| ModuleStub {
127                    module,
128                    ..ModuleStub::default()
129                });
130                entry.enum_defs.push(format_enum_def(name, &canonical));
131            }
132        }
133        for def in &self.traits {
134            let canonical = canonicalize_trait(def, prefix);
135            if let Some((module, name)) = module_and_name(&canonical.name) {
136                let entry = modules.entry(module.clone()).or_insert_with(|| ModuleStub {
137                    module,
138                    ..ModuleStub::default()
139                });
140                entry.trait_defs.push(format_trait_def(name, &canonical));
141            }
142        }
143        for def in &self.impls {
144            let canonical = canonicalize_impl(def, prefix);
145            if let Some(module) = impl_module(&canonical) {
146                modules.entry(module.clone()).or_insert_with(|| ModuleStub {
147                    module,
148                    ..ModuleStub::default()
149                });
150            }
151        }
152        modules.into_values().collect()
153    }
154
155    pub fn structs(&self) -> impl Iterator<Item = &StructDef> {
156        self.structs.iter()
157    }
158
159    pub fn enums(&self) -> impl Iterator<Item = &EnumDef> {
160        self.enums.iter()
161    }
162}
163
164#[derive(Clone, Debug, Default)]
165pub struct ModuleStub {
166    pub module: String,
167    pub struct_defs: Vec<String>,
168    pub enum_defs: Vec<String>,
169    pub trait_defs: Vec<String>,
170}
171
172impl ModuleStub {
173    pub fn is_empty(&self) -> bool {
174        self.struct_defs.is_empty() && self.enum_defs.is_empty() && self.trait_defs.is_empty()
175    }
176}
177
178#[derive(Clone)]
179pub struct StructBuilder {
180    def: StructDef,
181}
182
183impl StructBuilder {
184    pub fn new(name: impl Into<String>) -> Self {
185        StructBuilder {
186            def: StructDef {
187                name: name.into(),
188                type_params: Vec::new(),
189                trait_bounds: Vec::new(),
190                fields: Vec::new(),
191                visibility: Visibility::Public,
192            },
193        }
194    }
195
196    pub fn visibility(mut self, visibility: Visibility) -> Self {
197        self.def.visibility = visibility;
198        self
199    }
200
201    pub fn type_param(mut self, name: impl Into<String>) -> Self {
202        self.def.type_params.push(name.into());
203        self
204    }
205
206    pub fn trait_bound(mut self, bound: TraitBound) -> Self {
207        self.def.trait_bounds.push(bound);
208        self
209    }
210
211    pub fn field(mut self, field: StructField) -> Self {
212        self.def.fields.push(field);
213        self
214    }
215
216    pub fn finish(self) -> StructDef {
217        self.def
218    }
219}
220
221#[derive(Clone)]
222pub struct EnumBuilder {
223    def: EnumDef,
224}
225
226impl EnumBuilder {
227    pub fn new(name: impl Into<String>) -> Self {
228        EnumBuilder {
229            def: EnumDef {
230                name: name.into(),
231                type_params: Vec::new(),
232                trait_bounds: Vec::new(),
233                variants: Vec::new(),
234                visibility: Visibility::Public,
235            },
236        }
237    }
238
239    pub fn visibility(mut self, visibility: Visibility) -> Self {
240        self.def.visibility = visibility;
241        self
242    }
243
244    pub fn type_param(mut self, name: impl Into<String>) -> Self {
245        self.def.type_params.push(name.into());
246        self
247    }
248
249    pub fn trait_bound(mut self, bound: TraitBound) -> Self {
250        self.def.trait_bounds.push(bound);
251        self
252    }
253
254    pub fn variant(mut self, variant: EnumVariant) -> Self {
255        self.def.variants.push(variant);
256        self
257    }
258
259    pub fn finish(self) -> EnumDef {
260        self.def
261    }
262}
263
264#[derive(Clone)]
265pub struct TraitBuilder {
266    def: TraitDef,
267}
268
269impl TraitBuilder {
270    pub fn new(name: impl Into<String>) -> Self {
271        TraitBuilder {
272            def: TraitDef {
273                name: name.into(),
274                type_params: Vec::new(),
275                methods: Vec::new(),
276                visibility: Visibility::Public,
277            },
278        }
279    }
280
281    pub fn visibility(mut self, visibility: Visibility) -> Self {
282        self.def.visibility = visibility;
283        self
284    }
285
286    pub fn type_param(mut self, name: impl Into<String>) -> Self {
287        self.def.type_params.push(name.into());
288        self
289    }
290
291    pub fn method(mut self, method: TraitMethod) -> Self {
292        self.def.methods.push(method);
293        self
294    }
295
296    pub fn finish(self) -> TraitDef {
297        self.def
298    }
299}
300
301#[derive(Clone)]
302pub struct ImplBuilder {
303    block: ImplBlock,
304}
305
306impl ImplBuilder {
307    pub fn new(target_type: Type) -> Self {
308        ImplBuilder {
309            block: ImplBlock {
310                type_params: Vec::new(),
311                trait_name: None,
312                target_type,
313                methods: Vec::new(),
314                where_clause: Vec::new(),
315            },
316        }
317    }
318
319    pub fn for_trait(mut self, trait_name: impl Into<String>) -> Self {
320        self.block.trait_name = Some(trait_name.into());
321        self
322    }
323
324    pub fn type_param(mut self, name: impl Into<String>) -> Self {
325        self.block.type_params.push(name.into());
326        self
327    }
328
329    pub fn where_bound(mut self, bound: TraitBound) -> Self {
330        self.block.where_clause.push(bound);
331        self
332    }
333
334    pub fn method(mut self, method: FunctionDef) -> Self {
335        self.block.methods.push(method);
336        self
337    }
338
339    pub fn finish(self) -> ImplBlock {
340        self.block
341    }
342}
343
344#[derive(Clone)]
345pub struct TraitMethodBuilder {
346    method: TraitMethod,
347}
348
349impl TraitMethodBuilder {
350    pub fn new(name: impl Into<String>) -> Self {
351        TraitMethodBuilder {
352            method: TraitMethod {
353                name: name.into(),
354                type_params: Vec::new(),
355                params: Vec::new(),
356                return_type: None,
357                default_impl: None,
358            },
359        }
360    }
361
362    pub fn type_param(mut self, name: impl Into<String>) -> Self {
363        self.method.type_params.push(name.into());
364        self
365    }
366
367    pub fn param(mut self, param: FunctionParam) -> Self {
368        self.method.params.push(param);
369        self
370    }
371
372    pub fn return_type(mut self, ty: Type) -> Self {
373        self.method.return_type = Some(ty);
374        self
375    }
376
377    pub fn finish(self) -> TraitMethod {
378        self.method
379    }
380}
381
382#[derive(Clone)]
383pub struct FunctionBuilder {
384    function: FunctionDef,
385}
386
387impl FunctionBuilder {
388    pub fn new(name: impl Into<String>) -> Self {
389        let name = name.into();
390        FunctionBuilder {
391            function: FunctionDef {
392                name,
393                type_params: Vec::new(),
394                trait_bounds: Vec::new(),
395                params: Vec::new(),
396                return_type: None,
397                body: Vec::new(),
398                is_method: false,
399                visibility: Visibility::Public,
400            },
401        }
402    }
403
404    pub fn visibility(mut self, visibility: Visibility) -> Self {
405        self.function.visibility = visibility;
406        self
407    }
408
409    pub fn type_param(mut self, name: impl Into<String>) -> Self {
410        self.function.type_params.push(name.into());
411        self
412    }
413
414    pub fn trait_bound(mut self, bound: TraitBound) -> Self {
415        self.function.trait_bounds.push(bound);
416        self
417    }
418
419    pub fn param(mut self, param: FunctionParam) -> Self {
420        if param.is_self {
421            self.function.is_method = true;
422        }
423        self.function.params.push(param);
424        self
425    }
426
427    pub fn return_type(mut self, ty: Type) -> Self {
428        self.function.return_type = Some(ty);
429        self
430    }
431
432    pub fn finish(self) -> FunctionDef {
433        self.function
434    }
435}
436
437pub fn struct_field_decl(name: impl Into<String>, ty: Type) -> StructField {
438    StructField {
439        name: name.into(),
440        ty,
441        visibility: Visibility::Public,
442        ownership: FieldOwnership::Strong,
443        weak_target: None,
444    }
445}
446
447pub fn weak_struct_field_decl(name: impl Into<String>, ty: Type) -> StructField {
448    let span = ty.span;
449    let option = Type::new(TypeKind::Option(Box::new(ty.clone())), span);
450    StructField {
451        name: name.into(),
452        ty: option,
453        visibility: Visibility::Public,
454        ownership: FieldOwnership::Weak,
455        weak_target: Some(ty),
456    }
457}
458
459pub fn private_struct_field_decl(name: impl Into<String>, ty: Type) -> StructField {
460    StructField {
461        name: name.into(),
462        ty,
463        visibility: Visibility::Private,
464        ownership: FieldOwnership::Strong,
465        weak_target: None,
466    }
467}
468
469pub fn enum_variant(name: impl Into<String>) -> EnumVariant {
470    EnumVariant {
471        name: name.into(),
472        fields: None,
473    }
474}
475
476pub fn enum_variant_with(
477    name: impl Into<String>,
478    fields: impl IntoIterator<Item = Type>,
479) -> EnumVariant {
480    EnumVariant {
481        name: name.into(),
482        fields: Some(fields.into_iter().collect()),
483    }
484}
485
486pub fn trait_bound(
487    param: impl Into<String>,
488    traits: impl IntoIterator<Item = String>,
489) -> TraitBound {
490    TraitBound {
491        type_param: param.into(),
492        traits: traits.into_iter().collect(),
493    }
494}
495
496pub fn function_param(name: impl Into<String>, ty: Type) -> FunctionParam {
497    FunctionParam {
498        name: name.into(),
499        ty,
500        is_self: false,
501    }
502}
503
504pub fn self_param(ty: Option<Type>) -> FunctionParam {
505    FunctionParam {
506        name: "self".to_string(),
507        ty: ty.unwrap_or_else(|| Type::new(TypeKind::Infer, Span::dummy())),
508        is_self: true,
509    }
510}
511
512pub fn type_named(name: impl Into<String>) -> Type {
513    Type::new(TypeKind::Named(name.into()), Span::dummy())
514}
515
516pub fn type_unit() -> Type {
517    Type::new(TypeKind::Unit, Span::dummy())
518}
519
520pub fn type_unknown() -> Type {
521    Type::new(TypeKind::Unknown, Span::dummy())
522}
523
524fn function_signature_for(func: &FunctionDef) -> (String, FunctionSignature) {
525    let params: Vec<Type> = func.params.iter().map(|p| p.ty.clone()).collect();
526    let return_type = func
527        .return_type
528        .clone()
529        .unwrap_or_else(|| Type::new(TypeKind::Unit, Span::dummy()));
530    (
531        func.name.clone(),
532        FunctionSignature {
533            params,
534            return_type,
535            is_method: func.is_method,
536        },
537    )
538}
539
540fn module_and_name(name: &str) -> Option<(String, String)> {
541    if let Some((module, rest)) = name.rsplit_once("::") {
542        return Some((module.replace("::", "."), rest.to_string()));
543    }
544    if let Some((module, rest)) = name.rsplit_once('.') {
545        return Some((module.to_string(), rest.to_string()));
546    }
547    None
548}
549
550fn impl_module(impl_block: &ImplBlock) -> Option<String> {
551    match &impl_block.target_type.kind {
552        TypeKind::Named(name) => module_and_name(name).map(|(module, _)| module),
553        TypeKind::GenericInstance { name, .. } => module_and_name(name).map(|(module, _)| module),
554        _ => None,
555    }
556}
557
558fn format_struct_def(name: String, def: &StructDef) -> String {
559    let mut out = String::new();
560    if matches!(def.visibility, Visibility::Public) {
561        out.push_str("pub ");
562    }
563    out.push_str("struct ");
564    out.push_str(&name);
565    if !def.type_params.is_empty() {
566        out.push('<');
567        out.push_str(&def.type_params.join(", "));
568        out.push('>');
569    }
570    out.push('\n');
571    for field in &def.fields {
572        out.push_str("    ");
573        if matches!(field.visibility, Visibility::Public) {
574            out.push_str("pub ");
575        }
576        out.push_str(&field.name);
577        out.push_str(": ");
578        match field.ownership {
579            FieldOwnership::Weak => {
580                out.push_str("ref ");
581                if let Some(target) = &field.weak_target {
582                    out.push_str(&format_type(target));
583                } else {
584                    out.push_str(&format_type(&field.ty));
585                }
586            }
587            FieldOwnership::Strong => {
588                out.push_str(&format_type(&field.ty));
589            }
590        }
591        out.push('\n');
592    }
593    out.push_str("end\n");
594    out
595}
596
597fn format_enum_def(name: String, def: &EnumDef) -> String {
598    let mut out = String::new();
599    if matches!(def.visibility, Visibility::Public) {
600        out.push_str("pub ");
601    }
602    out.push_str("enum ");
603    out.push_str(&name);
604    if !def.type_params.is_empty() {
605        out.push('<');
606        out.push_str(&def.type_params.join(", "));
607        out.push('>');
608    }
609    out.push('\n');
610    for variant in &def.variants {
611        out.push_str("    ");
612        out.push_str(&variant.name);
613        if let Some(fields) = &variant.fields {
614            let parts: Vec<String> = fields.iter().map(format_type).collect();
615            out.push('(');
616            out.push_str(&parts.join(", "));
617            out.push(')');
618        }
619        out.push('\n');
620    }
621    out.push_str("end\n");
622    out
623}
624
625fn format_trait_def(name: String, def: &TraitDef) -> String {
626    let mut out = String::new();
627    if matches!(def.visibility, Visibility::Public) {
628        out.push_str("pub ");
629    }
630    out.push_str("trait ");
631    out.push_str(&name);
632    if !def.type_params.is_empty() {
633        out.push('<');
634        out.push_str(&def.type_params.join(", "));
635        out.push('>');
636    }
637    out.push('\n');
638    for method in &def.methods {
639        out.push_str("    ");
640        out.push_str(&format_trait_method(method));
641        out.push('\n');
642    }
643    out.push_str("end\n");
644    out
645}
646
647fn format_trait_method(method: &TraitMethod) -> String {
648    let mut out = String::new();
649    out.push_str("function ");
650    out.push_str(&method.name);
651    if !method.type_params.is_empty() {
652        out.push('<');
653        out.push_str(&method.type_params.join(", "));
654        out.push('>');
655    }
656    out.push('(');
657    out.push_str(
658        &method
659            .params
660            .iter()
661            .map(format_param_signature)
662            .collect::<Vec<_>>()
663            .join(", "),
664    );
665    out.push(')');
666    if let Some(ret) = &method.return_type {
667        if !matches!(ret.kind, TypeKind::Unit) {
668            out.push_str(": ");
669            out.push_str(&format_type(ret));
670        }
671    }
672    out
673}
674
675fn format_param_signature(param: &FunctionParam) -> String {
676    if param.is_self {
677        return "self".to_string();
678    }
679    if matches!(param.ty.kind, TypeKind::Infer) {
680        param.name.clone()
681    } else {
682        format!("{}: {}", param.name, format_type(&param.ty))
683    }
684}
685
686fn format_type(ty: &Type) -> String {
687    match &ty.kind {
688        TypeKind::Named(name) => {
689            let (_, simple) =
690                module_and_name(name).unwrap_or_else(|| (String::new(), name.clone()));
691            if simple.is_empty() {
692                name.clone()
693            } else {
694                simple
695            }
696        }
697        TypeKind::GenericInstance { name, type_args } => {
698            let (_, simple) =
699                module_and_name(name).unwrap_or_else(|| (String::new(), name.clone()));
700            let args = type_args
701                .iter()
702                .map(format_type)
703                .collect::<Vec<_>>()
704                .join(", ");
705            format!("{}<{}>", simple, args)
706        }
707        _ => format!("{}", ty),
708    }
709}
710
711fn canonicalize_struct(def: &StructDef, prefix: Option<&str>) -> StructDef {
712    let mut cloned = def.clone();
713    cloned.name = canonicalize_simple_name(&cloned.name, prefix);
714    for field in &mut cloned.fields {
715        field.ty = canonicalize_type(&field.ty, prefix);
716        if let Some(target) = &field.weak_target {
717            field.weak_target = Some(canonicalize_type(target, prefix));
718        }
719    }
720    cloned
721}
722
723fn canonicalize_enum(def: &EnumDef, prefix: Option<&str>) -> EnumDef {
724    let mut cloned = def.clone();
725    cloned.name = canonicalize_simple_name(&cloned.name, prefix);
726    for variant in &mut cloned.variants {
727        if let Some(fields) = &mut variant.fields {
728            for field in fields {
729                *field = canonicalize_type(field, prefix);
730            }
731        }
732    }
733    cloned
734}
735
736fn canonicalize_trait(def: &TraitDef, prefix: Option<&str>) -> TraitDef {
737    let mut cloned = def.clone();
738    cloned.name = canonicalize_simple_name(&cloned.name, prefix);
739    for method in &mut cloned.methods {
740        for param in &mut method.params {
741            param.ty = canonicalize_type(&param.ty, prefix);
742        }
743        if let Some(ret) = method.return_type.clone() {
744            method.return_type = Some(canonicalize_type(&ret, prefix));
745        }
746    }
747    cloned
748}
749
750fn canonicalize_impl(def: &ImplBlock, prefix: Option<&str>) -> ImplBlock {
751    let mut cloned = def.clone();
752    cloned.target_type = canonicalize_type(&cloned.target_type, prefix);
753    let struct_name = match &cloned.target_type.kind {
754        TypeKind::Named(name) => name.clone(),
755        TypeKind::GenericInstance { name, .. } => name.clone(),
756        _ => cloned.target_type.to_string(),
757    };
758    if let Some(trait_name) = &cloned.trait_name {
759        cloned.trait_name = Some(canonicalize_simple_name(trait_name, prefix));
760    }
761    for method in &mut cloned.methods {
762        for param in &mut method.params {
763            param.ty = canonicalize_type(&param.ty, prefix);
764        }
765        if let Some(ret) = method.return_type.clone() {
766            method.return_type = Some(canonicalize_type(&ret, prefix));
767        }
768        if let Some((_, rest)) = method.name.split_once(':') {
769            method.name = format!("{}:{}", struct_name, rest);
770        } else if let Some((_, rest)) = method.name.split_once('.') {
771            method.name = format!("{}.{}", struct_name, rest);
772        } else {
773            method.name = format!("{}:{}", struct_name, method.name);
774        }
775        #[cfg(debug_assertions)]
776        eprintln!("canonicalized method name -> {}", method.name);
777    }
778    cloned
779}
780
781fn canonicalize_type(ty: &Type, prefix: Option<&str>) -> Type {
782    use TypeKind as TK;
783    let mut canonical = ty.clone();
784    canonical.kind = match &ty.kind {
785        TK::Named(name) => TK::Named(canonicalize_simple_name(name, prefix)),
786        TK::GenericInstance { name, type_args } => TK::GenericInstance {
787            name: canonicalize_simple_name(name, prefix),
788            type_args: type_args
789                .iter()
790                .map(|arg| canonicalize_type(arg, prefix))
791                .collect(),
792        },
793        TK::Array(inner) => TK::Array(Box::new(canonicalize_type(inner, prefix))),
794        TK::Option(inner) => TK::Option(Box::new(canonicalize_type(inner, prefix))),
795        TK::Result(ok, err) => TK::Result(
796            Box::new(canonicalize_type(ok, prefix)),
797            Box::new(canonicalize_type(err, prefix)),
798        ),
799        TK::Ref(inner) => TK::Ref(Box::new(canonicalize_type(inner, prefix))),
800        TK::MutRef(inner) => TK::MutRef(Box::new(canonicalize_type(inner, prefix))),
801        TK::Map(key, value) => TK::Map(
802            Box::new(canonicalize_type(key, prefix)),
803            Box::new(canonicalize_type(value, prefix)),
804        ),
805        TK::Tuple(elements) => TK::Tuple(
806            elements
807                .iter()
808                .map(|element| canonicalize_type(element, prefix))
809                .collect(),
810        ),
811        TK::Union(types) => TK::Union(
812            types
813                .iter()
814                .map(|variant| canonicalize_type(variant, prefix))
815                .collect(),
816        ),
817        other => other.clone(),
818    };
819    canonical
820}
821
822fn canonicalize_simple_name(name: &str, prefix: Option<&str>) -> String {
823    if name.is_empty() {
824        return name.to_string();
825    }
826    if is_qualified_name(name) {
827        return name.replace("::", ".");
828    }
829    if let Some(prefix) = prefix {
830        if prefix.is_empty() {
831            return name.to_string();
832        }
833        return format!("{}.{}", prefix, name);
834    }
835    name.to_string()
836}
837
838fn is_qualified_name(name: &str) -> bool {
839    name.contains('.') || name.contains("::")
840}