decred.org/dcrdex@v1.0.3/client/intl/intl.go (about)

     1  // This code is available on the terms of the project LICENSE.md file,
     2  // also available online at https://blueoakcouncil.org/license/1.0.0.
     3  
     4  package intl
     5  
     6  const defaultLanguage = "en-US"
     7  
     8  // Trasnlation is a versioned localized string. Notes added to the english
     9  // translation will be presented to human translators.
    10  type Translation struct {
    11  	Version int
    12  	T       string
    13  	Notes   string // english only
    14  }
    15  
    16  var translations = map[string] /* lang */ map[string] /* caller ID */ map[string] /* translation ID */ *Translation{}
    17  
    18  // Registrar is used for registering translations for a specific language and
    19  // caller context.
    20  type Registrar struct {
    21  	callerID string
    22  	lang     string
    23  	m        map[string]*Translation
    24  }
    25  
    26  // NewRegistrar constructs a Registrar.
    27  func NewRegistrar(callerID string, lang string, preAlloc int) *Registrar {
    28  	callers, found := translations[lang]
    29  	if !found {
    30  		callers = make(map[string]map[string]*Translation)
    31  		translations[lang] = callers
    32  	}
    33  	m := make(map[string]*Translation, preAlloc)
    34  	callers[callerID] = m
    35  	return &Registrar{
    36  		callerID: callerID,
    37  		lang:     lang,
    38  		m:        m,
    39  	}
    40  }
    41  
    42  // Register registers a translation.
    43  func (r *Registrar) Register(translationID string, t *Translation) {
    44  	r.m[translationID] = t
    45  }
    46  
    47  // TranslationReport is a report of missing and extraneous translations.
    48  type TranslationReport struct {
    49  	Missing map[string] /* caller ID */ map[string]*Translation // English translation
    50  	Extras  []string                                            /* caller ID */
    51  }
    52  
    53  // Report generates a TranslationReport for each registered language.
    54  func Report() map[string] /* lang */ *TranslationReport {
    55  	reports := make(map[string]*TranslationReport)
    56  
    57  	for lang := range translations {
    58  		if lang == defaultLanguage {
    59  			continue
    60  		}
    61  		reports[lang] = &TranslationReport{
    62  			Missing: make(map[string]map[string]*Translation),
    63  		}
    64  	}
    65  	enUS := translations[defaultLanguage]
    66  	for callerID, enTranslations := range enUS {
    67  		for lang, callers := range translations {
    68  			if lang == defaultLanguage {
    69  				continue
    70  			}
    71  			r := reports[lang]
    72  			ts := callers[callerID]
    73  			if ts == nil {
    74  				ts = make(map[string]*Translation)
    75  			}
    76  			missing := r.Missing[callerID]
    77  			if missing == nil {
    78  				missing = make(map[string]*Translation)
    79  				r.Missing[callerID] = missing
    80  			}
    81  			for translationID, enTranslation := range enTranslations {
    82  				t := ts[translationID]
    83  				if t == nil || t.Version < enTranslation.Version {
    84  					missing[translationID] = enTranslation
    85  				}
    86  			}
    87  		}
    88  	}
    89  
    90  	for lang, callers := range translations {
    91  		if lang == defaultLanguage {
    92  			continue
    93  		}
    94  		r := reports[lang]
    95  		for callerID, ts := range callers {
    96  			enTranslations := enUS[callerID]
    97  			for translationID := range ts {
    98  				if enTranslations[translationID] == nil {
    99  					r.Extras = append(r.Extras, callerID+" -> "+translationID)
   100  				}
   101  			}
   102  		}
   103  	}
   104  
   105  	return reports
   106  }