') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); })(); GitHub - genelet/determined: Build customized JSON and HCL Unmarshaler with Determined · GitHub
Skip to content

Repository files navigation

determined

Determined marshals and unmarshals JSON data to go struct containing interfaces determined at run-time.

GoDoc

Note: The HCL parsing feature has been extracted and moved to a separate Github package github.com/genelet/horizon. The old HCL code in this package is frozen for compatibility reasons.

Installation

go get github.com/genelet/determined

Introduction

The core Golang package encoding/json is an exceptional library for managing JSON data. However, to decode the interface type, it necessitates writing a customized Unmarshaler for the target object. While this isn’t typically a challenging task, it often results in repetitive code for different types of objects and packages.

Therefore, determined was created to streamline the coding process and enhance productivity.

Usage

To decode JSON to an object containing interface types, use det.JsonUnmarshal.

// JsonUnmarshal unmarshals JSON data with interfaces determined by spec.//// - dat: JSON data// - current: object as pointer// - spec: *schema.Struct// - ref: struct map, with key being string name and value reference to structfuncJsonUnmarshal(dat []byte, currentinterface{}, spec*schema.Struct, refmap[string]interface{}) error

You first need to define the structure of your interfaces using schema.NewStruct from the github.com/genelet/schema package.

Example

Here is an example of how to use determined to decode JSON data where fields are interfaces.

package main
import (
"fmt""github.com/genelet/determined/det""github.com/genelet/schema"
)
typegeostruct {
Namestring`json:"name"`Shapeinter`json:"shape"`
}
typeinterinterface {
Area() float32
}
typesquarestruct {
SXint`json:"sx"`SYint`json:"sy"`
}
func (self*square) Area() float32 {
returnfloat32(self.SX*self.SY)
}
typecirclestruct {
Radiusfloat32`json:"radius"`
}
func (self*circle) Area() float32 {
return3.14159*self.Radius
}
typetoystruct {
Geogeo`json:"geo"`ToyNamestring`json:"toy_name"`Pricefloat32`json:"price"`
}
typechildstruct {
Brandmap[string]*toy`json:"brand"`Ageint`json:"age"`
}
funcmain() {
data1:=`{ "age" : 5, "brand" : { "abc1" : { "toy_name" : "roblox", "price" : 99.9, "geo" : { "name" : "medium shape", "shape" : { "radius" : 1.234 } } }, "def2" : { "toy_name" : "minecraft", "price" : 9.9, "geo" : { "name" : "square shape", "shape" : { "sx" : 5, "sy" : 6 } } } } }`// Define the structure of the interfaces for the specific dataspec, err:=schema.NewStruct(
"child", map[string]interface{}{
"Brand": map[string][2]interface{}{
"abc1":[2]interface{}{"toy", map[string]interface{}{
"Geo": [2]interface{}{
"geo", map[string]interface{}{"Shape": "circle"}}}},
"def2":[2]interface{}{"toy", map[string]interface{}{
"Geo": [2]interface{}{
"geo", map[string]interface{}{"Shape": "square"}}}},
},
},
)
iferr!=nil {
panic(err)
}
// Map string names to actual struct pointersref:=map[string]interface{}{
"toy": &toy{}, "geo": &geo{}, "circle": &circle{}, "square": &square{},
}
c:=new(child)
err=det.JsonUnmarshal([]byte(data1), c, spec, ref)
iferr!=nil {
panic(err)
}
fmt.Printf("Age: %v\n", c.Age)
fmt.Printf("Brand abc1: %#v\n", c.Brand["abc1"])
fmt.Printf("Brand abc1 Shape: %#v\n", c.Brand["abc1"].Geo.Shape)
fmt.Printf("Brand def2: %#v\n", c.Brand["def2"])
fmt.Printf("Brand def2 Shape: %#v\n", c.Brand["def2"].Geo.Shape)
}

For more details on how to construct the spec using NewStruct, please refer to DOCUMENT.md.

About

Build customized JSON and HCL Unmarshaler with Determined

Topics

Resources

Stars

24 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages