Files
elmprodvpn/selective-vpn-api/app/resolver/io_helpers.go

136 lines
2.2 KiB
Go

package resolver
import (
"encoding/json"
"os"
"strconv"
"strings"
)
func ReadLinesAllowMissing(path string) []string {
data, err := os.ReadFile(path)
if err != nil {
return nil
}
return strings.Split(strings.ReplaceAll(string(data), "\r\n", "\n"), "\n")
}
func LoadJSONMap(path string) map[string]any {
data, err := os.ReadFile(path)
if err != nil {
return map[string]any{}
}
var out map[string]any
if err := json.Unmarshal(data, &out); err != nil {
return map[string]any{}
}
return out
}
func SaveJSON(data any, path string) {
tmp := path + ".tmp"
b, err := json.MarshalIndent(data, "", " ")
if err != nil {
return
}
_ = os.WriteFile(tmp, b, 0o644)
_ = os.Rename(tmp, path)
}
func parseAnyInt(raw any) (int, bool) {
switch v := raw.(type) {
case int:
return v, true
case int64:
return int(v), true
case float64:
return int(v), true
case json.Number:
n, err := v.Int64()
if err != nil {
return 0, false
}
return int(n), true
case string:
s := strings.TrimSpace(v)
if s == "" {
return 0, false
}
n, err := strconv.Atoi(s)
if err != nil {
return 0, false
}
return n, true
default:
return 0, false
}
}
func LoadResolverPrecheckLastRun(path string) int {
m := LoadJSONMap(path)
if len(m) == 0 {
return 0
}
v, ok := parseAnyInt(m["last_run"])
if !ok || v <= 0 {
return 0
}
return v
}
func LoadResolverLiveBatchTarget(path string, fallback, minV, maxV int) int {
if fallback < minV {
fallback = minV
}
if fallback > maxV {
fallback = maxV
}
m := LoadJSONMap(path)
if len(m) == 0 {
return fallback
}
raw := m["live_batch_next_target"]
if raw == nil {
raw = m["live_batch_target"]
}
v, ok := parseAnyInt(raw)
if !ok || v <= 0 {
return fallback
}
if v < minV {
v = minV
}
if v > maxV {
v = maxV
}
return v
}
func LoadResolverLiveBatchNXHeavyPct(path string, fallback, minV, maxV int) int {
if fallback < minV {
fallback = minV
}
if fallback > maxV {
fallback = maxV
}
m := LoadJSONMap(path)
if len(m) == 0 {
return fallback
}
raw := m["live_batch_nxheavy_next_pct"]
if raw == nil {
raw = m["live_batch_nxheavy_pct"]
}
v, ok := parseAnyInt(raw)
if !ok {
return fallback
}
if v < minV {
v = minV
}
if v > maxV {
v = maxV
}
return v
}