ksuid genration return string in go - string

I am using below function to generate ksuid in byte format but i need it to return ksuid in string format.
I tried returning id.string() value but i am getting below error
error:
cannot use id.String() (value of type string) as id_return value in return statement.
I would like it to assign the return string value like below (string instead of byte)
var id_gen string = genKsuid()
type id []byte
type id_return string
func genKsuid() id {
id, err := ksuid.NewRandomWithTime(time.Now())
if err != nil {
log.Fatal(err)
}
fmt.Printf("ksuid: %s\n", id.String())
return id.Bytes()
}
var id_gen []byte = genKsuid()

Change your function to
func genKsuid() string {
id, err := ksuid.NewRandomWithTime(time.Now())
if err != nil {
log.Fatal(err)
}
fmt.Printf("ksuid: %s\n", id.String())
return id.String()
}

Related

How to remove string pattern and all the string behind that pattern?

For Example :
package main
import "fmt"
func main() {
pattern := "helloworld."
myString := "foo.bar.helloworld.qwerty.zxc.helloworld.asd"
fmt.Println(removeFromPattern(pattern, myString))
}
func removeFromPattern(p, ms string) string {
// I confused here (in efficient way)
}
Wanted output :
qwerty.zxc.helloworld.asd
How do I get that wanted output, also how to remove the first pattern and all the strings behind that pattern from myString ?
1- Using _, after, _ = strings.Cut(ms, p), try this:
func removeFromPattern(p, ms string) (after string) {
_, after, _ = strings.Cut(ms, p) // before and after sep.
return
}
Which uses strings.Index :
// Cut slices s around the first instance of sep,
// returning the text before and after sep.
// The found result reports whether sep appears in s.
// If sep does not appear in s, cut returns s, "", false.
func Cut(s, sep string) (before, after string, found bool) {
if i := Index(s, sep); i >= 0 {
return s[:i], s[i+len(sep):], true
}
return s, "", false
}
2- Using strings.Index, try this:
func removeFromPattern(p, ms string) string {
i := strings.Index(ms, p)
if i == -1 {
return ""
}
return ms[i+len(p):]
}
3- Using strings.Split, try this:
func removeFromPattern(p, ms string) string {
a := strings.Split(ms, p)
if len(a) != 2 {
return ""
}
return a[1]
}
4- Using regexp, try this
func removeFromPattern(p, ms string) string {
a := regexp.MustCompile(p).FindStringSubmatch(ms)
if len(a) < 2 {
return ""
}
return a[1]
}
strings.Split is enough
func main() {
pattern := "helloworld."
myString := "foo.bar.helloworld.qwerty.zxc"
res := removeFromPattern(pattern, myString)
fmt.Println(res)
}
func removeFromPattern(p, ms string) string {
parts := strings.Split(ms, p)
if len(parts) > 1 {
return parts[1]
}
return ""
}
func removeFromPattern(p, ms string) string {
return strings.ReplaceAll(ms, p, "")
}
func main() {
pattern := "helloworld."
myString := "foo.bar.helloworld.qwerty.zxc"
res := removeFromPattern(pattern, myString)
fmt.Println(res)
}

unexpected EOF with fmt.Scanner

If I want to scan through a string, I can do this:
package main
import (
"fmt"
"strings"
)
func main() {
r := strings.NewReader("west north east")
for {
var s string
_, e := fmt.Fscan(r, &s)
fmt.Printf("%q %v\n", s, e)
if e != nil { break }
}
}
Result:
"west" <nil>
"north" <nil>
"east" <nil>
"" EOF
I recently discovered fmt.Scanner [1], so I thought I would try to implement
it. I came up with this:
package main
import (
"fmt"
"strings"
)
type comma struct { tok string }
func (c *comma) Scan(state fmt.ScanState, verb rune) error {
tok, err := state.Token(false, func(r rune) bool {
return r != ','
})
if err != nil {
return err
}
if _, _, err := state.ReadRune(); err != nil {
if len(tok) == 0 {
return err
}
}
c.tok = string(tok)
return nil
}
func main() {
r := strings.NewReader("west,north,east")
for {
var c comma
_, e := fmt.Fscan(r, &c)
fmt.Printf("%q %v\n", c.tok, e)
if e != nil { break }
}
}
Result:
"west" <nil>
"north" <nil>
"east" <nil>
"" unexpected EOF
So the result is pretty close, but what bothers me is the unexpected EOF. Is
it possible to just get a regular EOF with a custom fmt.Scanner? Am I doing
something wrong here, or is this a bug?
https://golang.org/pkg/fmt#Scanner
Thanks to Ian Lance Taylor on the golang-nuts list, he suggested to panic
the error instead of return. In the Go code, Fscan calls a function
doScan, which in turn calls a function errorHandler [1]. This last function
uses recover to turn any panic into regular error. This program gives
idential output to my original example:
package main
import (
"fmt"
"strings"
)
type comma struct { tok string }
func (c *comma) Scan(state fmt.ScanState, verb rune) error {
tok, err := state.Token(false, func(r rune) bool {
return r != ','
})
if err != nil { return err }
if _, _, err := state.ReadRune(); err != nil {
if len(tok) == 0 {
panic(err)
}
}
c.tok = string(tok)
return nil
}
func main() {
r := strings.NewReader("west,north,east")
for {
var c comma
_, err := fmt.Fscan(r, &c)
fmt.Printf("%q %v\n", c.tok, err)
if err != nil { break }
}
}
https://github.com/golang/go/blob/go1.16.4/src/fmt/scan.go#L1056-L1067

uint8 to literal string representation

I'm trying to access the HackerNews API endpoint with a given ID 22024283 which represents a particular news item e.g https://hacker-news.firebaseio.com/v0/22024283.json
This itemID is of type uint8and I need to convert this to it's string representation to insert into the URL.
I cannot use strconv.Itoa(int(id)) as that will produce the number 91 and not preserve 22024283.
Any help on this would be appreciated. Here is my code so far, function of interest is GetHackerNewsItem():
import (
"fmt"
"io/ioutil"
"net/http"
"strconv"
"time"
)
//Client represents connection to firebase datastore
type Client struct {
BASEURI string
Version string
Suffix string
}
type Item struct {
id int `json:"id"`
itemtype string `json:"itemtype"`
by string `json:"by"`
time time.Time `json:"time"`
kids []int `json:"kids"`
url string `json:"url"`
score int `json:"score"`
text string `json:"text"`
title string `json:"title"`
descendants int `json:"descendants"`
}
//Connect to firebase datastore
func NewHackerNewsClient() *Client {
var client Client
client.BASEURI = "https://hacker-news.firebaseio.com/"
client.Version = "v0"
client.Suffix = ".json"
return &client
}
func MakeHTTPRequest(url string) ([]byte, error) {
response, err := http.Get(url)
if err != nil {
fmt.Printf("The http request failed with the error %s\n", err)
}
body, err := ioutil.ReadAll(response.Body)
if err != nil {
fmt.Printf("Failed to read response data with the error %s\n", err)
return nil, err
}
return body, nil
}
func (client *Client) GetHackerNewsItem(id uint8) []byte {
itemID := strconv.Itoa(int(id))
fmt.Printf(itemID)
url := client.BASEURI + client.Version + itemID + client.Suffix
fmt.Printf(url)
item, _ := MakeHTTPRequest(url)
fmt.Print(item)
return item
}
func (client *Client) GetTopStories() {
url := client.BASEURI + client.Version + "/topstories/" + client.Suffix
itemArray, _ := MakeHTTPRequest(url)
for i := 0; i < len(itemArray); i++ {
item := client.GetHackerNewsItem(itemArray[i])
fmt.Print(item)
}
}
func main() {
client := NewHackerNewsClient()
client.GetTopStories()
}
itemArray, _ := MakeHTTPRequest(url)
itemArray must be unmarshaled like
dat := make([]uint64, 0)
if err := json.Unmarshal(itemArray, &dat); err != nil {
panic(err)
}

how to return struct duitonary in golang funtion

i need to retrun struct duitonary from a funtion and when it run script i'm gettting cannot use res (type []exceldata) as type []struct {} in return argument
I have created struct in my go script and i added values to that and added to array now i need to return it to main funtion
package main
import (
"fmt"
"database/sql"
_ "github.com/go-sql-driver/mysql"
"github.com/360EntSecGroup-Skylar/excelize"
"log"
)
type exceldata struct {
username string
rfid string
user string
}
func read() []struct{} {
exdata := exceldata{}
res := []exceldata{}
f, err := excelize.OpenFile("./required_details.xlsx")
if err != nil {
fmt.Println(err)
return res
}
// Get value from cell by given worksheet name and axis.
/*cell, err := f.GetCellValue("Sheet1", "A566")
if err != nil {
fmt.Println(err)
return
}
fmt.Println(cell)*/
// Get all the rows in the Sheet1.
rows, err := f.GetRows("Sheet1")
for _, row := range rows {
if row[0] != "eof"{
exdata.username = row[0]
exdata.rfid = row[1]
exdata.user = row[2]
res = append(res, exdata)
fmt.Println(res)
}else{
return res
}
}
return res;
}
func main() {
fmt.Println("Go MySQL Tutorial")
resexceldata := []exceldata{}
resexceldata =read()
fmt.Println("Routes are Loded.")
}
You are already difining exceldata as a type, so you should use that type:
type exceldata struct
...
func read() []exceldata {
...
}

Reading from reader until a string is reached

I am trying to write a function to keep reading from a buffered reader until I hit a certain string, then to stop reading and return everything read prior to that string.
In other words, I want to do the same thing as reader.ReadString() does, except taking a string instead of a single byte.
For instance:
mydata, err := reader.ReadString("\r\n.\r\n") //obviously will not compile
How can I do this?
Thanks in advance,
Twichy
Amendment 1: Previous attempt
Here is my previous attempt; its badly written and doesnt work but hopefully it demonstrates what I am trying to do.
func readDotData(reader *bufio.Reader)(string, error){
delims := []byte{ '\r', '\n', '.', '\r', '\n'}
curpos := 0
var buffer []byte
for {
curpos = 0
data, err := reader.ReadSlice(delims[0])
if err!=nil{ return "", err }
buffer = append(buffer, data...)
for {
curpos++
b, err := reader.ReadByte()
if err!=nil{ return "", err }
if b!=delims[curpos]{
for curpos >= 0{
buffer = append(buffer, delims[curpos])
curpos--
}
break
}
if curpos == len(delims){
return string(buffer[len(buffer)-1:]), nil
}
}
}
panic("unreachable")
}
package main
import (
"bytes"
"fmt"
"log"
)
type reader interface {
ReadString(delim byte) (line string, err error)
}
func read(r reader, delim []byte) (line []byte, err error) {
for {
s := ""
s, err = r.ReadString(delim[len(delim)-1])
if err != nil {
return
}
line = append(line, []byte(s)...)
if bytes.HasSuffix(line, delim) {
return line[:len(line)-len(delim)], nil
}
}
}
func main() {
src := bytes.NewBufferString("123deli456elim789delimABCdelimDEF")
for {
b, err := read(src, []byte("delim"))
if err != nil {
log.Fatal(err)
}
fmt.Printf("%q\n", b)
}
}
Playground
Output:
"123deli456elim789"
"ABC"
2009/11/10 23:00:00 EOF
http://play.golang.org/p/BpA5pOc-Rn
package main
import (
"bytes"
"fmt"
)
func main() {
b := bytes.NewBuffer([]byte("Hello, playground!\r\n.\r\nIrrelevant trailer."))
c := make([]byte, 0, b.Len())
for {
p := b.Bytes()
if bytes.Equal(p[:5], []byte("\r\n.\r\n")) {
fmt.Println(string(c))
return
}
c = append(c, b.Next(1)...)
}
}
For example,
package main
import (
"bufio"
"bytes"
"fmt"
"strings"
)
var delim = []byte{'\r', '\n', '.', '\r', '\n'}
func ScanLines(data []byte, atEOF bool) (advance int, token []byte, err error) {
if atEOF && len(data) == 0 {
return 0, nil, nil
}
for i := 0; i+len(delim) <= len(data); {
j := i + bytes.IndexByte(data[i:], delim[0])
if j < i {
break
}
if bytes.Equal(data[j+1:j+len(delim)], delim[1:]) {
// We have a full delim-terminated line.
return j + len(delim), data[0:j], nil
}
i = j + 1
}
// If we're at EOF, we have a final, non-terminated line. Return it.
if atEOF {
return len(data), data, nil
}
// Request more data.
return 0, nil, nil
}
func main() {
delims := string(delim)
input := "1234" + delims + "5678" + delims + "1234567901234567890" + delims
scanner := bufio.NewScanner(strings.NewReader(input))
scanner.Split(ScanLines)
for scanner.Scan() {
fmt.Printf("%s\n", scanner.Text())
}
if err := scanner.Err(); err != nil {
fmt.Printf("Invalid input: %s", err)
}
}
Output:
1234
5678
1234567901234567890
Because you have the same byte in the string, you can do it as below:
func readWithEnd(reader *bufio.Reader) ([]byte, error) {
message, err := reader.ReadBytes('#')
if err != nil {
return nil, err
}
a1, err := reader.ReadByte()
if err != nil {
return nil, err
}
message = append(message, a1)
if a1 != '\t' {
message2, err := readWithEnd(reader)
if err != nil {
return nil, err
}
ret := append(message, message2...)
return ret, nil
}
a2, err := reader.ReadByte()
if err != nil {
return nil, err
}
message = append(message, a2)
if a2 != '#' {
message2, err := readWithEnd(reader)
if err != nil {
return nil, err
}
ret := append(message, message2...)
return ret, nil
}
return message, nil
}
This is the sample that can recognize the "#\t#" in TCP connection

Resources