diff --git a/stringmanip/runes.go b/stringmanip/runes.go new file mode 100644 index 0000000..fd56b8e --- /dev/null +++ b/stringmanip/runes.go @@ -0,0 +1,96 @@ +package stringmanip + +/* + The MIT License (MIT) + + Copyright (c) 2016 Sergey Kamardin + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ +// Source: https://github.com/gobwas/glob/blob/master/util/runes/runes.go + +func IndexRune(str string, r rune) int { + s := []rune(str) + for i, c := range s { + if c == r { + return i + } + } + return -1 +} + +func LastIndexRune(str string, needle rune) int { + s := []rune(str) + needles := []rune{needle} + ls, ln := len(s), len(needles) + + switch { + case ln == 0: + if ls == 0 { + return 0 + } + return ls + case ln == 1: + return IndexLastRune(s, needles[0]) + case ln == ls: + if EqualRunes(s, needles) { + return 0 + } + return -1 + case ln > ls: + return -1 + } + +head: + for i := ls - 1; i >= 0 && i >= ln; i-- { + for y := ln - 1; y >= 0; y-- { + if s[i-(ln-y-1)] != needles[y] { + continue head + } + } + + return i - ln + 1 + } + + return -1 +} + +func IndexLastRune(s []rune, r rune) int { + for i := len(s) - 1; i >= 0; i-- { + if s[i] == r { + return i + } + } + + return -1 +} + +func EqualRunes(a, b []rune) bool { + if len(a) == len(b) { + for i := 0; i < len(a); i++ { + if a[i] != b[i] { + return false + } + } + + return true + } + + return false +} diff --git a/stringmanip/strings.go b/stringmanip/strings.go new file mode 100644 index 0000000..1711e4c --- /dev/null +++ b/stringmanip/strings.go @@ -0,0 +1,17 @@ +package stringmanip + +// Substring provides a safe way to extract a substring from a UTF-8 string. +// From this discussion: +// https://groups.google.com/d/msg/golang-nuts/cGq1Irv_5Vs/0SKoj49BsWQJ +func Substring(s string, p, l int) string { + if p < 0 || l <= 0 { + return "" + } + c := []rune(s) + if p > len(c) { + return "" + } else if p+l > len(c) || p+l < p { + return string(c[p:]) + } + return string(c[p : p+l]) +}