func TranslateWithLocale()

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
}