LCOV - code coverage report
Current view: top level - shared/util - i18n.go Coverage Total Hit
Test: coverage.lcov Lines: 0.0 % 59 0
Test Date: 2026-04-14 06:42:22 Functions: - 0 0

            Line data    Source code
       1              : // Package util は i18n 関連の共通ヘルパー関数を提供します。
       2              : // 旧 shared/i18n/loader.go から移植された wrapWithPath, deepMerge, flatten などを含みます。
       3              : package util
       4              : 
       5              : import (
       6              :         "fmt"
       7              :         "os"
       8              :         "strings"
       9              : 
      10              :         "gopkg.in/yaml.v3"
      11              : )
      12              : 
      13              : // ReadYAMLFile はファイルパスを受け取り、YAML を map[string]any にパースします。
      14            0 : func ReadYAMLFile(path string) (map[string]any, error) {
      15            0 :         data, err := os.ReadFile(path)
      16            0 :         if err != nil {
      17            0 :                 return nil, fmt.Errorf("read file: %w", err)
      18            0 :         }
      19            0 :         out := map[string]any{}
      20            0 :         if err := yaml.Unmarshal(data, &out); err != nil {
      21            0 :                 return nil, fmt.Errorf("unmarshal yaml: %w", err)
      22            0 :         }
      23            0 :         return out, nil
      24              : }
      25              : 
      26              : // WrapWithPath は ["ui","page","home"] + {"title":"Home"} を
      27              : // {"ui":{"page":{"home":{"title":"Home"}}}} の形に変換します。
      28            0 : func WrapWithPath(prefix []string, in map[string]any) map[string]any {
      29            0 :         if len(prefix) == 0 {
      30            0 :                 return in
      31            0 :         }
      32            0 :         last := prefix[len(prefix)-1]
      33            0 :         if len(prefix) == 1 {
      34            0 :                 return map[string]any{last: in}
      35            0 :         }
      36            0 :         return map[string]any{prefix[0]: WrapWithPath(prefix[1:], in)}
      37              : }
      38              : 
      39              : // DeepMerge は src の内容を dst に再帰的にマージします。
      40              : // ネスト構造が衝突する場合、map[string]any 同士なら再帰的に統合します。
      41            0 : func DeepMerge(dst, src map[string]any) error {
      42            0 :         for k, v := range src {
      43            0 :                 if dv, ok := dst[k]; ok {
      44            0 :                         // 両方 map[string]any の場合のみ再帰マージ
      45            0 :                         dm, dok := dv.(map[string]any)
      46            0 :                         sm, sok := v.(map[string]any)
      47            0 :                         if dok && sok {
      48            0 :                                 if err := DeepMerge(dm, sm); err != nil {
      49            0 :                                         return err
      50            0 :                                 }
      51            0 :                                 continue
      52              :                         }
      53              :                 }
      54            0 :                 dst[k] = v
      55              :         }
      56            0 :         return nil
      57              : }
      58              : 
      59              : // Flatten はネスト構造を "a.b.c" 形式のキーでフラット化します。
      60            0 : func Flatten(prefix string, in map[string]any, out map[string]any) {
      61            0 :         for k, v := range in {
      62            0 :                 key := k
      63            0 :                 if prefix != "" {
      64            0 :                         key = prefix + "." + k
      65            0 :                 }
      66            0 :                 switch vv := v.(type) {
      67            0 :                 case map[string]any:
      68            0 :                         Flatten(key, vv, out)
      69            0 :                 case map[any]any: // yaml.v2系がこれを返すことがある
      70            0 :                         m2 := make(map[string]any, len(vv))
      71            0 :                         for kk, vv2 := range vv {
      72            0 :                                 if s, ok := kk.(string); ok {
      73            0 :                                         m2[s] = vv2
      74            0 :                                 }
      75              :                         }
      76            0 :                         Flatten(key, m2, out)
      77            0 :                 default:
      78            0 :                         out[key] = vv
      79              :                 }
      80              :         }
      81              : }
      82              : 
      83              : // DetectLocale はパスからロケールコード (ja, en, etc.) を抽出します。
      84            0 : func DetectLocale(path string) string {
      85            0 :         normalized := strings.ReplaceAll(path, `\`, "/")
      86            0 :         segs := strings.Split(normalized, "/")
      87            0 :         for _, cand := range []string{"ja", "en"} {
      88            0 :                 for _, s := range segs {
      89            0 :                         if s == cand {
      90            0 :                                 return cand
      91            0 :                         }
      92              :                 }
      93              :         }
      94            0 :         return "ja"
      95              : }
        

Generated by: LCOV version 2.3.1-1