fqname.gno
2.36 Kb ยท 77 lines
1// Package fqname provides utilities for handling fully qualified identifiers in
2// Gno. A fully qualified identifier typically includes a package path followed
3// by a dot (.) and then the name of a variable, function, type, or other
4// package-level declaration.
5package fqname
6
7import (
8 "strings"
9)
10
11// Parse splits a fully qualified identifier into its package path and name
12// components. It handles cases with and without slashes in the package path.
13//
14// pkgpath, name := fqname.Parse("gno.land/p/demo/avl.Tree")
15// ufmt.Sprintf("Package: %s, Name: %s\n", id.Package, id.Name)
16// // Output: Package: gno.land/p/demo/avl, Name: Tree
17func Parse(fqname string) (pkgpath, name string) {
18 // Find the index of the last slash.
19 lastSlashIndex := strings.LastIndex(fqname, "/")
20 if lastSlashIndex == -1 {
21 // No slash found, handle it as a simple package name with dot notation.
22 dotIndex := strings.LastIndex(fqname, ".")
23 if dotIndex == -1 {
24 return fqname, ""
25 }
26 return fqname[:dotIndex], fqname[dotIndex+1:]
27 }
28
29 // Get the part after the last slash.
30 afterSlash := fqname[lastSlashIndex+1:]
31
32 // Check for a dot in the substring after the last slash.
33 dotIndex := strings.Index(afterSlash, ".")
34 if dotIndex == -1 {
35 // No dot found after the last slash
36 return fqname, ""
37 }
38
39 // Split at the dot to separate the base and the suffix.
40 base := fqname[:lastSlashIndex+1+dotIndex]
41 suffix := afterSlash[dotIndex+1:]
42
43 return base, suffix
44}
45
46// Construct a qualified identifier.
47//
48// fqName := fqname.Construct("gno.land/r/demo/foo20", "Token")
49// fmt.Println("Fully Qualified Name:", fqName)
50// // Output: gno.land/r/demo/foo20.Token
51func Construct(pkgpath, name string) string {
52 // TODO: ensure pkgpath is valid - and as such last part does not contain a dot.
53 if name == "" {
54 return pkgpath
55 }
56 return pkgpath + "." + name
57}
58
59// RenderLink creates a formatted link for a fully qualified identifier.
60// If the package path starts with "gno.land", it converts it to a markdown link.
61// If the domain is different or missing, it returns the input as is.
62func RenderLink(pkgPath, slug string) string {
63 if strings.HasPrefix(pkgPath, "gno.land") {
64 pkgLink := strings.TrimPrefix(pkgPath, "gno.land")
65 if slug != "" {
66 return "[" + pkgPath + "](" + pkgLink + ")." + slug
67 }
68
69 return "[" + pkgPath + "](" + pkgLink + ")"
70 }
71
72 if slug != "" {
73 return pkgPath + "." + slug
74 }
75
76 return pkgPath
77}