in lunes.go [176:327]
func TranslateWithLocale(layout string, value string, locale Locale) (string, error) {
var err error
var sb strings.Builder
var layoutOffset, valueOffset int
sb.Grow(len(layout) + 32)
for layoutOffset < len(layout) {
written := false
var lookupTab, stdTab []string
switch c := int(layout[layoutOffset]); c {
case 'J': // January, Jan
if len(layout) >= layoutOffset+3 && layout[layoutOffset:layoutOffset+3] == "Jan" {
layoutElem := ""
if len(layout) >= layoutOffset+7 && layout[layoutOffset:layoutOffset+7] == "January" {
layoutElem = "January"
lookupTab = locale.LongMonthNames()
stdTab = longMonthNamesStd
} else if !startsWithLowerCase(layout[layoutOffset+3:]) {
layoutElem = "Jan"
lookupTab = locale.ShortMonthNames()
stdTab = shortMonthNamesStd
}
if layoutElem == "" {
break
}
if len(lookupTab) == 0 {
return "", newUnsupportedLayoutElemError(layoutElem, locale)
}
layoutOffset += len(layoutElem)
valueOffset, err = writeLayoutValue(layoutElem, lookupTab, stdTab, valueOffset, value, &sb)
if err != nil {
return "", err
}
written = true
}
case 'M': // Monday, Mon
if len(layout) >= layoutOffset+3 && layout[layoutOffset:layoutOffset+3] == "Mon" {
layoutElem := ""
if len(layout) >= layoutOffset+6 && layout[layoutOffset:layoutOffset+6] == "Monday" {
layoutElem = "Monday"
lookupTab = locale.LongDayNames()
stdTab = longDayNamesStd
} else if !startsWithLowerCase(layout[layoutOffset+3:]) {
layoutElem = "Mon"
lookupTab = locale.ShortDayNames()
stdTab = shortDayNamesStd
}
if layoutElem == "" {
break
}
if len(lookupTab) == 0 {
return "", newUnsupportedLayoutElemError(layoutElem, locale)
}
layoutOffset += len(layoutElem)
valueOffset, err = writeLayoutValue(layoutElem, lookupTab, stdTab, valueOffset, value, &sb)
if err != nil {
return "", err
}
written = true
}
case 'P', 'p': // PM, pm
if len(layout) >= layoutOffset+2 && unicode.ToUpper(rune(layout[layoutOffset+1])) == 'M' {
var layoutElem string
// day-periods case matters for the time package parsing functions
if c == 'p' {
layoutElem = "pm"
stdTab = dayPeriodsStdLower
} else {
layoutElem = "PM"
stdTab = dayPeriodsStdUpper
}
lookupTab = locale.DayPeriods()
if len(lookupTab) == 0 {
return "", newUnsupportedLayoutElemError(layoutElem, locale)
}
layoutOffset += 2
valueOffset, err = writeLayoutValue(layoutElem, lookupTab, stdTab, valueOffset, value, &sb)
if err != nil {
return "", err
}
written = true
}
case '_': // _2, _2006, __2
// Although no translations happens here, it is still necessary to calculate the
// variable size of `_` values, so the layoutOffset stays synchronized with
// its layout element counterpart.
if len(layout) >= layoutOffset+2 && layout[layoutOffset+1] == '2' {
var layoutElemSize int
// _2006 is really a literal _, followed by the long year placeholder
if len(layout) >= layoutOffset+5 && layout[layoutOffset+1:layoutOffset+5] == "2006" {
if len(value) >= valueOffset+5 {
layoutElemSize = 5 // _2006
}
} else {
if len(value) >= valueOffset+2 {
layoutElemSize = 2 // _2
}
}
if layoutElemSize > 0 {
layoutOffset += layoutElemSize
valueOffset, err = writeNextNonSpaceValue(value, valueOffset, layoutElemSize, &sb)
if err != nil {
return "", err
}
written = true
}
}
if len(layout) >= layoutOffset+3 && layout[layoutOffset+1] == '_' && layout[layoutOffset+2] == '2' {
if len(value) >= valueOffset+3 {
layoutOffset += 3
valueOffset, err = writeNextNonSpaceValue(value, valueOffset, 3, &sb)
if err != nil {
return "", err
}
written = true
}
}
}
if !written {
var writtenSize int
if len(value) > valueOffset {
writtenSize, err = sb.WriteRune(rune(value[valueOffset]))
if err != nil {
return "", err
}
}
layoutOffset++
valueOffset += writtenSize
}
}
if len(value) >= valueOffset {
sb.WriteString(value[valueOffset:])
}
return sb.String(), nil
}