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}