Last active
January 29, 2025 05:40
-
-
Save mikeschinkel/d745132837361264f884e6c2de3d2900 to your computer and use it in GitHub Desktop.
Example use-case for github.com/micromdm/plist where `UnmarshalPlist()` needs access to `pval`
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"bytes" | |
"fmt" | |
"os" | |
"github.com/micromdm/plist" | |
) | |
// Value is key to my use-case | |
type Value struct { | |
Value any | |
} | |
// UnmarshalPlist only captures the value if the type of `value` matches the type | |
// of `v`, the reflect.Value. Otherwise value is equal to `nil`. If I change the | |
// type of `value` to any specific type, it captures all values for that type but | |
// sets all `*Value` objects to `nil`. I guess I could literally create a slice | |
// of reflect types and create a zero instance of each and loop through them | |
// until f() no longer returns an error but that would probably cur performance | |
// in half, if not 1/10th or worse. | |
func (v *Value) UnmarshalPlist(f func(interface{}) error) (err error) { | |
var value any | |
err = f(&value) | |
v.Value = value | |
return nil | |
} | |
type ManifestKey struct { | |
Name string `plist:"pfm_name"` | |
Default Value `plist:"pfm_default,omitempty"` | |
Subkeys []ManifestKey `plist:"pfm_subkeys,omitempty"` | |
} | |
type ProfileManifest struct { | |
Domain string `plist:"pfm_domain"` | |
Subkeys []ManifestKey `plist:"pfm_subkeys"` | |
} | |
func main() { | |
r := bytes.NewBuffer([]byte(dockYAML)) | |
decoder := plist.NewXMLDecoder(r) | |
pm := ProfileManifest{} | |
err := decoder.Decode(&pm) | |
if err != nil { | |
fmt.Printf("Failed to decode profile manifest: %s", err.Error()) | |
os.Exit(1) | |
} | |
fmt.Println(pm) | |
} | |
// dockYAML is a subset of https://github.com/ProfileManifests/ProfileManifests/tree/master/Manifests/ManifestsApple/com.apple.dock.plist | |
const dockYAML = `<?xml version="1.0" encoding="UTF-8"?> | |
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | |
<plist version="1.0"> | |
<dict> | |
<key>pfm_domain</key> | |
<string>com.apple.dock</string> | |
<key>pfm_subkeys</key> | |
<array> | |
<dict> | |
<key>pfm_name</key> | |
<string>static-apps</string> | |
<key>pfm_subkeys</key> | |
<array> | |
<dict> | |
<key>pfm_name</key> | |
<string>StaticItem</string> | |
<key>pfm_subkeys</key> | |
<array> | |
<dict> | |
<key>pfm_default</key> | |
<string>file-tile</string> | |
<key>pfm_name</key> | |
<string>tile-type</string> | |
</dict> | |
<dict> | |
<key>pfm_name</key> | |
<string>tile-data</string> | |
<key>pfm_subkeys</key> | |
<array> | |
<dict> | |
<key>pfm_name</key> | |
<string>label</string> | |
</dict> | |
<dict> | |
<key>pfm_name</key> | |
<string>file-label</string> | |
</dict> | |
<dict> | |
<key>pfm_name</key> | |
<string>file-type</string> | |
</dict> | |
<dict> | |
<key>pfm_name</key> | |
<string>file-data</string> | |
<key>pfm_subkeys</key> | |
<array> | |
<dict> | |
<key>pfm_name</key> | |
<string>_CFURLString</string> | |
</dict> | |
<dict> | |
<key>pfm_name</key> | |
<string>_CFURLStringType</string> | |
</dict> | |
</array> | |
</dict> | |
<dict> | |
<key>pfm_name</key> | |
<string>url</string> | |
</dict> | |
</array> | |
</dict> | |
</array> | |
</dict> | |
</array> | |
</dict> | |
</array> | |
</dict> | |
</plist>` |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Here is the ultimate resolution: micromdm/plist#46