Skip to content

Split Describe into DescribeList/DescribeWithCallback/Describe (Fixes #125) - #126

Merged
p0dalirius merged 1 commit into
mainfrom
feature-describe-list-callback
Jul 21, 2026
Merged

Split Describe into DescribeList/DescribeWithCallback/Describe (Fixes #125)#126
p0dalirius merged 1 commit into
mainfrom
feature-describe-list-callback

Conversation

@p0dalirius

Copy link
Copy Markdown
Collaborator

Linked Issue

Closes #125

Root Cause

Every structure's Describe(indent int) built its lines with an inline strings.Repeat(" │ ", indent) prefix and wrote them straight to stdout with fmt.Printf. Rendered content and rendering (indentation + output sink) were entangled, and composite types propagated the coupling by calling child.Describe(indent+1). There was no way to obtain a description as data or route it to a non-stdout sink.

Fix Description

Introduce a shared utils/describe package and split every Describe into three layers:

  • DescribeList() []string — the content at indentation depth 0 (source of truth). Composites build theirs by nesting each child's DescribeList one level deeper via describe.Nest, replacing the old child.Describe(indent+1) calls.
  • DescribeWithCallback(indent int, printf func(string, ...any) (int, error)) — prepends indent indentation units to each line and routes it to a fmt.Printf-like callback.
  • Describe(indent int) — unchanged signature and behavior; delegates to DescribeWithCallback(indent, fmt.Printf).

utils/describe provides Unit, Nest, WithCallback, and the Printf type alias. The callback is fmt.Printf-shaped so fmt.Printf can be passed directly, and any logger / fmt.Fprintf wrapper works as a sink.

Converted all 15 implementations: ace/mask, ace/header, ace/applicationdata, ace.AccessControlEntry, identity, sid, object (×3), acl (×4), securitydescriptor/header, securitydescriptor.NtSecurityDescriptor.

How Verified

  • go build ./..., go vet ./..., gofmt -l — all clean.
  • go test ./... — all packages pass, including existing describe/SDDL/round-trip suites.
  • New consistency test asserts Describe(0) output equals DescribeList() joined with newlines, and that DescribeWithCallback delivers the same lines; a second test checks indent prefixing at indent=2.

Test Coverage

Added: utils/describe/describe_test.go (TestNest, TestWithCallback); securitydescriptor/NtSecurityDescriptor_describe_test.go (TestDescribeLayeringConsistency, TestDescribeIndentPrefix).
Existing: ace and securitydescriptor describe tests continue to pass unchanged, confirming byte-identical output at indent=0.

Scope of Change

  • Files changed: utils/describe/describe.go (new), utils/describe/describe_test.go (new), securitydescriptor/NtSecurityDescriptor_describe_test.go (new), plus the 15 structure files listed above.
  • Submodule pointer updated: no
  • Behavioral changes outside the fix: none at indent=0. NtSecurityDescriptor now indents its root/footer line at indent>0 (previously always column 0); this is unobservable at the normal top-level Describe(0) call.

Risk and Rollout

Additive API (two new methods per type); Describe behavior is preserved. Safe to merge — no wire-format or default-output changes.

…125)

Introduce the utils/describe package (Unit, Nest, WithCallback, Printf) and
refactor every structure's Describe into three layers:

  - DescribeList() []string        content at indentation depth 0
  - DescribeWithCallback(indent,    prefixes each line and routes it to a
                         printf)    fmt.Printf-like callback
  - Describe(indent)                delegates to DescribeWithCallback(indent,
                                    fmt.Printf); behavior unchanged

Composite structures build their list by nesting each child's DescribeList
one level deeper via describe.Nest, replacing the previous child.Describe
(indent+1) calls. Output is byte-identical at indent 0.
@p0dalirius
p0dalirius merged commit b1a3135 into main Jul 21, 2026
5 checks passed
@p0dalirius
p0dalirius deleted the feature-describe-list-callback branch July 21, 2026 08:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant