Initial migration
This commit is contained in:
commit
6347e2f1fe
32 changed files with 3472 additions and 0 deletions
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
.null-ls*
|
||||
chrono.txt
|
||||
.DS_Store
|
39
cmd/main.go
Normal file
39
cmd/main.go
Normal file
|
@ -0,0 +1,39 @@
|
|||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func read_from_c(c chan int, b chan int) {
|
||||
for item := range c {
|
||||
fmt.Printf("%d", item)
|
||||
number_multiplied := item * item
|
||||
b <- number_multiplied
|
||||
}
|
||||
close(b)
|
||||
}
|
||||
|
||||
func read_from_b(b chan int) {
|
||||
for item := range b {
|
||||
fmt.Printf("%d", item)
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
fmt.Println("main() started")
|
||||
c := make(chan int)
|
||||
b := make(chan int)
|
||||
|
||||
fmt.Println("Operation started")
|
||||
go func() {
|
||||
fmt.Println("Running writer")
|
||||
for i := 1; i < 10; i++ {
|
||||
fmt.Printf("Adding %v to channel c", i)
|
||||
c <- i
|
||||
}
|
||||
close(c)
|
||||
}()
|
||||
|
||||
go read_from_c(c, b)
|
||||
for item := range b {
|
||||
fmt.Printf("%d", item)
|
||||
}
|
||||
}
|
3
go.mod
Normal file
3
go.mod
Normal file
|
@ -0,0 +1,3 @@
|
|||
module go_sandbox
|
||||
|
||||
go 1.21.3
|
93
internal/chrono/chrono.go
Normal file
93
internal/chrono/chrono.go
Normal file
|
@ -0,0 +1,93 @@
|
|||
package chrono
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"time"
|
||||
)
|
||||
|
||||
type ChronoEntry struct {
|
||||
Date, Time, Action string
|
||||
}
|
||||
|
||||
type ParsedChronoEntry struct {
|
||||
StartTime time.Time
|
||||
Action string
|
||||
Duration string
|
||||
}
|
||||
|
||||
func Chrono() {
|
||||
// Return path of an executable
|
||||
exPath, err := os.Executable()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
exDir := filepath.Dir(exPath)
|
||||
fmt.Println(exDir)
|
||||
// Return path of the current directory
|
||||
path, err := os.Getwd()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// Join paths
|
||||
textFilePath := filepath.Join(path, "chrono.txt")
|
||||
// Read file with chrono data
|
||||
readFile, err := os.Open(textFilePath)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer readFile.Close()
|
||||
|
||||
fileScanner := bufio.NewScanner(readFile)
|
||||
fileScanner.Split(bufio.ScanLines)
|
||||
var fileLines []string
|
||||
for fileScanner.Scan() {
|
||||
fileLines = append(fileLines, fileScanner.Text())
|
||||
}
|
||||
// Prepare slice for data
|
||||
parse_result := make([]ChronoEntry, 0)
|
||||
result := make([]ParsedChronoEntry, 0)
|
||||
r := regexp.MustCompile(
|
||||
`(?P<date>\d{2}\s\w*\s\d{4})\s+at\s+(?P<time>\d{2}:\d{2}):\s+(?P<action>.*)`,
|
||||
)
|
||||
// Read lines from parsed data
|
||||
for _, line := range fileLines {
|
||||
// Find matches in line
|
||||
m := r.FindStringSubmatch(line)
|
||||
// Prepare dict for storing data
|
||||
result := make(map[string]string)
|
||||
// Parsing line and appending to result
|
||||
for i, name := range r.SubexpNames() {
|
||||
if i != 0 && name != "" {
|
||||
result[name] = m[i]
|
||||
}
|
||||
}
|
||||
chrono_entry := ChronoEntry{result["date"], result["time"], result["action"]}
|
||||
parse_result = append(parse_result, chrono_entry)
|
||||
}
|
||||
for index, element := range parse_result {
|
||||
layout := "02 Jan 2006-15:04"
|
||||
timestamp := fmt.Sprintf("%s-%s", element.Date, element.Time)
|
||||
t, err := time.Parse(layout, timestamp)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if index == 0 {
|
||||
k := ParsedChronoEntry{StartTime: t, Action: element.Action, Duration: "0"}
|
||||
result = append(result, k)
|
||||
continue
|
||||
} else {
|
||||
delta := t.Sub(result[index-1].StartTime)
|
||||
result[index-1].Duration = delta.String()
|
||||
if delta == time.Duration(0) {
|
||||
delta = time.Duration(time.Minute)
|
||||
}
|
||||
k := ParsedChronoEntry{t, element.Action, delta.String()}
|
||||
result = append(result, k)
|
||||
}
|
||||
}
|
||||
fmt.Println(result)
|
||||
}
|
18
internal/chrono/timedelta.go
Normal file
18
internal/chrono/timedelta.go
Normal file
|
@ -0,0 +1,18 @@
|
|||
package chrono
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TimeDelta() {
|
||||
t1 := time.Now()
|
||||
t2 := t1.Add(time.Second * 341)
|
||||
|
||||
diff := t2.Sub(t1)
|
||||
time := time.Time{}.Add(diff)
|
||||
string_time := time.Format("15:04:05")
|
||||
fmt.Println(string_time)
|
||||
fmt.Println(reflect.TypeOf(string_time))
|
||||
}
|
14
internal/learning/arrays.go
Normal file
14
internal/learning/arrays.go
Normal file
|
@ -0,0 +1,14 @@
|
|||
package learning
|
||||
|
||||
import "fmt"
|
||||
|
||||
func ArraysBasics() {
|
||||
var a [2]string
|
||||
a[0] = "Hello"
|
||||
a[1] = "World"
|
||||
fmt.Println(a[0], a[1])
|
||||
fmt.Println(a)
|
||||
|
||||
primes := [6]int{2, 3, 5, 7, 11, 13}
|
||||
fmt.Println(primes)
|
||||
}
|
47
internal/learning/closures.go
Normal file
47
internal/learning/closures.go
Normal file
|
@ -0,0 +1,47 @@
|
|||
package learning
|
||||
|
||||
import "fmt"
|
||||
|
||||
func adder() func(int) int {
|
||||
sum := 0
|
||||
return func(x int) int {
|
||||
fmt.Println("-------")
|
||||
fmt.Printf("Current sum= %d\n", sum)
|
||||
fmt.Printf("i= %d\n", x)
|
||||
sum += x
|
||||
fmt.Printf("New sum= %d\n", sum)
|
||||
fmt.Println("-------")
|
||||
return sum
|
||||
}
|
||||
}
|
||||
|
||||
func ClosuresLearning() {
|
||||
pos := adder()
|
||||
for i := 0; i < 10; i++ {
|
||||
fmt.Println(
|
||||
pos(i),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func FibonacciLearning() func() int {
|
||||
fib_sequence := []int{0, 1}
|
||||
var last_element int
|
||||
return func() int {
|
||||
fmt.Println(fib_sequence)
|
||||
|
||||
if len(fib_sequence) >= 2 {
|
||||
// Get first sum element
|
||||
sumOne := fib_sequence[len(fib_sequence)-1]
|
||||
// Get second sum element
|
||||
sumTwo := fib_sequence[len(fib_sequence)-2]
|
||||
fmt.Println(sumOne)
|
||||
fmt.Println(sumTwo)
|
||||
// sum them up
|
||||
last_element = sumOne + sumTwo
|
||||
fib_sequence = append(fib_sequence, last_element)
|
||||
}
|
||||
last_element = fib_sequence[len(fib_sequence)-1]
|
||||
return last_element
|
||||
}
|
||||
}
|
18
internal/learning/defer.go
Normal file
18
internal/learning/defer.go
Normal file
|
@ -0,0 +1,18 @@
|
|||
package learning
|
||||
|
||||
import "fmt"
|
||||
|
||||
func DeferLearn() {
|
||||
defer fmt.Println("world")
|
||||
fmt.Println("hello")
|
||||
}
|
||||
|
||||
func DeferStackingLearn() {
|
||||
fmt.Println("counting")
|
||||
|
||||
for i := 0; i < 10; i++ {
|
||||
defer fmt.Println(i)
|
||||
}
|
||||
|
||||
fmt.Println("Done!")
|
||||
}
|
36
internal/learning/errors.go
Normal file
36
internal/learning/errors.go
Normal file
|
@ -0,0 +1,36 @@
|
|||
package learning
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Declaring MyError structure
|
||||
type MyError struct {
|
||||
When time.Time
|
||||
What string
|
||||
}
|
||||
|
||||
// Declaring pointer method for MyError called Error that returns string
|
||||
func (e *MyError) Error() string {
|
||||
return fmt.Sprintf("at %v, %s", e.When, e.What)
|
||||
}
|
||||
|
||||
// error type: default go interface for returning string with error
|
||||
func run() error {
|
||||
// Returning pointer to new instance of MyError with provided arguments
|
||||
return &MyError{
|
||||
time.Now(),
|
||||
"it didn't work!",
|
||||
}
|
||||
}
|
||||
|
||||
func ErrorLearning() {
|
||||
// Checking that error, returned from run() is not equal to nil
|
||||
if err := run(); err != nil {
|
||||
// Printing created error to fmt
|
||||
fmt.Println(err)
|
||||
}
|
||||
}
|
||||
|
||||
i,err := strconv.Atoi("42")
|
20
internal/learning/func_values.go
Normal file
20
internal/learning/func_values.go
Normal file
|
@ -0,0 +1,20 @@
|
|||
package learning
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
)
|
||||
|
||||
func compute(fn func(float64, float64) float64) float64 {
|
||||
return fn(3, 4)
|
||||
}
|
||||
|
||||
func FuncAsValues() {
|
||||
hypot := func(x, y float64) float64 {
|
||||
return math.Sqrt(x*x + y*y)
|
||||
}
|
||||
fmt.Println(hypot(5,12))
|
||||
|
||||
fmt.Println(compute(hypot))
|
||||
fmt.Println(compute(math.Pow))
|
||||
}
|
41
internal/learning/interfaces.go
Normal file
41
internal/learning/interfaces.go
Normal file
|
@ -0,0 +1,41 @@
|
|||
package learning
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
)
|
||||
|
||||
type InterfaceVertex struct {
|
||||
X, Y float64
|
||||
}
|
||||
|
||||
type Abser interface {
|
||||
Abs() float64
|
||||
}
|
||||
|
||||
func InterfaceLearning() {
|
||||
var a Abser
|
||||
f := MyFloat(-math.Sqrt2)
|
||||
v := InterfaceVertex{3, 4}
|
||||
|
||||
a = f // a MyFloat implemets Abser
|
||||
a = &v // a *InterfaceVertex implemets Abser
|
||||
|
||||
// In following line, v is InterfaceVertex (not *InterfaceVertex)
|
||||
// and does NOT implement Abser
|
||||
// a = v
|
||||
fmt.Println(a.Abs())
|
||||
}
|
||||
|
||||
type MyFloat float64
|
||||
|
||||
func (f MyFloat) Abs() float64 {
|
||||
if f < 0 {
|
||||
return float64(-f)
|
||||
}
|
||||
return float64(f)
|
||||
}
|
||||
|
||||
func (v *InterfaceVertex) Abs() float64 {
|
||||
return math.Sqrt(v.X*v.X + v.Y*v.Y)
|
||||
}
|
47
internal/learning/interfaces_2.go
Normal file
47
internal/learning/interfaces_2.go
Normal file
|
@ -0,0 +1,47 @@
|
|||
package learning
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
)
|
||||
|
||||
// Объявляем интерфейс I с сигнатурой метода M()
|
||||
type I interface {
|
||||
M()
|
||||
}
|
||||
|
||||
// Объявляем структуру T с атрибутом S
|
||||
type T struct {
|
||||
S string
|
||||
}
|
||||
|
||||
// Имплементируем метод интерфейса M() для структуры T
|
||||
func (t *T) M() {
|
||||
fmt.Println(t.S)
|
||||
}
|
||||
|
||||
// Объявляем тип F
|
||||
type F float64
|
||||
|
||||
// Имплементируем метод интерфейса M() для типа F
|
||||
func (f F) M() {
|
||||
fmt.Println(f)
|
||||
}
|
||||
|
||||
func InterfaceLearningTwo() {
|
||||
// Объявляем переменную i типа I (интерфейс)
|
||||
var i I
|
||||
|
||||
// Присваиваем переменной i экземпляр струтуры T, у которой S = "Hello"
|
||||
i = &T{"Hello"}
|
||||
describe(i)
|
||||
i.M()
|
||||
|
||||
i = F(math.Pi)
|
||||
describe(i)
|
||||
i.M()
|
||||
}
|
||||
|
||||
func describe(i I) {
|
||||
fmt.Printf("(%v, %T)\n", i, i)
|
||||
}
|
64
internal/learning/maps.go
Normal file
64
internal/learning/maps.go
Normal file
|
@ -0,0 +1,64 @@
|
|||
package learning
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type MapVertex struct {
|
||||
Lat, Long float64
|
||||
}
|
||||
|
||||
var m map[string]MapVertex
|
||||
|
||||
func MapLearning() {
|
||||
m = make(map[string]MapVertex)
|
||||
fmt.Println(m)
|
||||
|
||||
m["Foo"] = MapVertex{
|
||||
1.1, 2.2,
|
||||
}
|
||||
fmt.Println(m)
|
||||
}
|
||||
|
||||
func MapExercise(str_to_count string) map[string]int {
|
||||
// fmt.Println("Hello")
|
||||
test_map := make(map[string]int) // Creating resulting map
|
||||
|
||||
// Iterating through string
|
||||
for _, char := range str_to_count {
|
||||
// Converting char to actually readable char
|
||||
var converted_char string = string(char)
|
||||
// Checking if this character contains in map keys
|
||||
amount_of_char_in_map, is_inside := test_map[converted_char]
|
||||
|
||||
if is_inside {
|
||||
// Get current amount of characters
|
||||
test_map[converted_char] = amount_of_char_in_map + 1
|
||||
} else {
|
||||
test_map[converted_char] = 1
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Println(test_map)
|
||||
return test_map
|
||||
}
|
||||
|
||||
func MapsLearningWords(string_to_parse string) map[string]int {
|
||||
// Declaring resulting map
|
||||
test_map := make(map[string]int)
|
||||
|
||||
// Splitting string to words
|
||||
var splitted_string []string = strings.Split(string_to_parse, " ")
|
||||
for _, word := range splitted_string {
|
||||
amount_of_words_in_map, is_inside := test_map[word]
|
||||
|
||||
if is_inside {
|
||||
// Get current amount of characters
|
||||
test_map[word] = amount_of_words_in_map + 1
|
||||
} else {
|
||||
test_map[word] = 1
|
||||
}
|
||||
}
|
||||
return test_map
|
||||
}
|
30
internal/learning/methods.go
Normal file
30
internal/learning/methods.go
Normal file
|
@ -0,0 +1,30 @@
|
|||
package learning
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
)
|
||||
|
||||
type MethodsVertex struct {
|
||||
X, Y float64
|
||||
}
|
||||
|
||||
func (v MethodsVertex) Abs() float64 {
|
||||
return math.Sqrt(v.X*v.X + v.Y*v.Y)
|
||||
}
|
||||
|
||||
func MethodsLearning() {
|
||||
v := MethodsVertex{3, 5}
|
||||
fmt.Println(v.Abs())
|
||||
}
|
||||
|
||||
func (v MethodsVertex) Scale(f float64) {
|
||||
v.X = v.X * f
|
||||
v.Y = v.Y * f
|
||||
}
|
||||
|
||||
func PointersMethodsLearning() {
|
||||
v := MethodsVertex{3,4}
|
||||
v.Scale(10)
|
||||
fmt.Println(v.Abs())
|
||||
}
|
17
internal/learning/pointers.go
Normal file
17
internal/learning/pointers.go
Normal file
|
@ -0,0 +1,17 @@
|
|||
package learning
|
||||
|
||||
import "fmt"
|
||||
|
||||
func PointersLearn() {
|
||||
i, j := 42, 2701
|
||||
|
||||
p := &i // point to i
|
||||
fmt.Println(p) // read address if i
|
||||
fmt.Println(*p) // read i through the pointer
|
||||
*p = 21 // set i through the pointer
|
||||
fmt.Println(i) // see the new value of i
|
||||
|
||||
p = &j // point to j
|
||||
*p = *p / 37 // divide j through the pointer
|
||||
fmt.Println(j) // see the new value of j
|
||||
}
|
10
internal/learning/range.go
Normal file
10
internal/learning/range.go
Normal file
|
@ -0,0 +1,10 @@
|
|||
package learning
|
||||
|
||||
import "fmt"
|
||||
|
||||
func RangeLearning(){
|
||||
var pow = []int{1,2,4,8,16,32,62,28}
|
||||
for index, value := range pow {
|
||||
fmt.Printf("2**%d = %d\n", index, value)
|
||||
}
|
||||
}
|
51
internal/learning/slices.go
Normal file
51
internal/learning/slices.go
Normal file
|
@ -0,0 +1,51 @@
|
|||
package learning
|
||||
|
||||
import "fmt"
|
||||
|
||||
func SlicesLearning() {
|
||||
primes := [6]int{2, 3, 5, 7, 11, 13}
|
||||
var s []int = primes[1:4]
|
||||
var ss []int = primes[:]
|
||||
fmt.Println(s)
|
||||
fmt.Println(ss)
|
||||
}
|
||||
|
||||
func SliceEnhanced() {
|
||||
s := []int{2, 3, 5, 7, 11, 13}
|
||||
printSlice(s)
|
||||
|
||||
// Slice the slice to give it zero length.
|
||||
s = s[:0]
|
||||
printSlice(s)
|
||||
|
||||
// Extend its length.
|
||||
s = s[:4]
|
||||
printSlice(s)
|
||||
|
||||
// Drop its first two values.
|
||||
s = s[2:]
|
||||
printSlice(s)
|
||||
}
|
||||
|
||||
func printSlice(s []int) {
|
||||
fmt.Printf("len=%d cap=%d %v\n", len(s), cap(s), s)
|
||||
}
|
||||
|
||||
func SlicesMake() {
|
||||
a := make([]int, 5)
|
||||
printSliceMake("a", a)
|
||||
|
||||
b := make([]int, 0, 5)
|
||||
printSliceMake("b", b)
|
||||
|
||||
c := b[:2]
|
||||
printSliceMake("c", c)
|
||||
|
||||
d := c[2:5]
|
||||
printSliceMake("d", d)
|
||||
}
|
||||
|
||||
func printSliceMake(s string, x []int) {
|
||||
fmt.Printf("%s len=%d cap=%d %v\n",
|
||||
s, len(x), cap(x), x)
|
||||
}
|
46
internal/learning/stringers.go
Normal file
46
internal/learning/stringers.go
Normal file
|
@ -0,0 +1,46 @@
|
|||
package learning
|
||||
|
||||
import "fmt"
|
||||
|
||||
type Person struct {
|
||||
Name string
|
||||
Age int
|
||||
}
|
||||
|
||||
func(p Person) String() string {
|
||||
return fmt.Sprintf("%v (%v years)", p.Name, p.Age)
|
||||
}
|
||||
|
||||
func StringersLearnings(){
|
||||
a := Person{"Arthur Dent", 42}
|
||||
z := Person{"Jopka Slona", 9001}
|
||||
fmt.Println(a, z)
|
||||
}
|
||||
|
||||
// Stringer exercise - IP address
|
||||
|
||||
type IPAddr [4]byte
|
||||
|
||||
func (ip IPAddr) String() string {
|
||||
// Bruteforce way
|
||||
// return fmt.Sprintf("%v.%v.%v.%v", ip[0], ip[1], ip[2], ip[3])
|
||||
// For-loop way
|
||||
result := ""
|
||||
for i := 0; i < len(ip); i++ {
|
||||
if i > 0 {
|
||||
result += "."
|
||||
}
|
||||
result += fmt.Sprintf("%v", ip[i])
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func StringersExercise(){
|
||||
hosts := map[string]IPAddr{
|
||||
"loopback": {127, 0, 0, 1},
|
||||
"googleDNS": {8, 8, 8, 8},
|
||||
}
|
||||
for name, ip := range hosts {
|
||||
fmt.Printf("%v: %v\n", name, ip)
|
||||
}
|
||||
}
|
26
internal/learning/struct.go
Normal file
26
internal/learning/struct.go
Normal file
|
@ -0,0 +1,26 @@
|
|||
package learning
|
||||
|
||||
import "fmt"
|
||||
|
||||
type Vertex struct {
|
||||
X int
|
||||
Y int
|
||||
}
|
||||
|
||||
type SomeStruct struct {
|
||||
X int
|
||||
Y string
|
||||
Z bool
|
||||
U float32
|
||||
J float64
|
||||
}
|
||||
|
||||
func StructLearning() {
|
||||
v := Vertex{1, 2}
|
||||
vv := SomeStruct{}
|
||||
p := &v
|
||||
v.Y = 123 // setting Y value of v via '.'
|
||||
p.X = 1e9 // setting X value of v via pointer to v. Syntax sugar for (*p).X
|
||||
fmt.Println(v)
|
||||
fmt.Println(vv)
|
||||
}
|
18
internal/learning/switch.go
Normal file
18
internal/learning/switch.go
Normal file
|
@ -0,0 +1,18 @@
|
|||
package learning
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
func SwitchCase() {
|
||||
fmt.Println("Go runs on: ")
|
||||
switch os := runtime.GOOS; os {
|
||||
case "darwin":
|
||||
fmt.Println("OS X")
|
||||
case "linux":
|
||||
fmt.Println("Linux")
|
||||
default:
|
||||
fmt.Printf("%s. \n", os)
|
||||
}
|
||||
}
|
41
internal/learning/type_assertions.go
Normal file
41
internal/learning/type_assertions.go
Normal file
|
@ -0,0 +1,41 @@
|
|||
package learning
|
||||
|
||||
import "fmt"
|
||||
|
||||
func TypeAssertionLearning() {
|
||||
// Declaring i variable with empty interface and containing "Hello" string
|
||||
var i interface{} = "Hello"
|
||||
// Type asserting interface i with string type
|
||||
s := i.(string)
|
||||
// Since type assertion returns underlying string value, this will print "Hello"
|
||||
fmt.Println(s)
|
||||
|
||||
// Type assertion can return second boolean value, that will tell if type is correct
|
||||
s, ok := i.(string)
|
||||
fmt.Println(s, ok)
|
||||
|
||||
// If assertion is false - then ok will be false and f will be zero value of type
|
||||
f, ok := i.(float64)
|
||||
fmt.Println(f, ok)
|
||||
|
||||
// If assertion returns false and not second arg provided - panic will be triggered
|
||||
// f = i.(float64)
|
||||
// fmt.Println(f)
|
||||
}
|
||||
|
||||
func do(i interface{}) {
|
||||
switch v := i.(type) {
|
||||
case int:
|
||||
fmt.Printf("Twice %v is %v\n", v, v*2)
|
||||
case string:
|
||||
fmt.Printf("%q is %v bytes long\n", v, len(v))
|
||||
default:
|
||||
fmt.Printf("I don't know about type %T!\n", v)
|
||||
}
|
||||
}
|
||||
|
||||
func TypeSwitchLearnings() {
|
||||
do(21)
|
||||
do("hello")
|
||||
do(true)
|
||||
}
|
33
internal/pointers/pointers.go
Normal file
33
internal/pointers/pointers.go
Normal file
|
@ -0,0 +1,33 @@
|
|||
package pointers
|
||||
|
||||
import "fmt"
|
||||
|
||||
// PointersPlayground - функция для демонстрации работы
|
||||
// указателей на адреса
|
||||
func PointersPlayground() {
|
||||
name := "Anton"
|
||||
var ptr *string
|
||||
|
||||
// Присваиваем адрес в памяти name к указателю
|
||||
// Т.е. адрес переменной name мы присваиваем
|
||||
// указателю prt с типом string
|
||||
// Если бы у нас был указатель с типом *int например
|
||||
// То код ниже дал бы ошибку
|
||||
ptr = &name
|
||||
|
||||
fmt.Println("Value of ponter is", ptr)
|
||||
fmt.Println("Address of the variable", &name)
|
||||
}
|
||||
|
||||
// PointersValues - функция для демонстрации того, как
|
||||
// получить значение из адреса в памяти
|
||||
func PointersValues() {
|
||||
name := "Antoshka"
|
||||
var ptr *string
|
||||
|
||||
ptr = &name
|
||||
|
||||
// * Используется чтобы получить значение из переменной
|
||||
// с типом "адрес в памяти" (&)
|
||||
fmt.Println(*ptr)
|
||||
}
|
9
internal/test/sqrt.go
Normal file
9
internal/test/sqrt.go
Normal file
|
@ -0,0 +1,9 @@
|
|||
package test
|
||||
|
||||
func SqrtExercise(x float64) float64 {
|
||||
z := float64(1)
|
||||
for i:=0; i<10; i++ {
|
||||
z -= (z*z-x)/(2*z)
|
||||
}
|
||||
return z
|
||||
}
|
1
regex.txt
Normal file
1
regex.txt
Normal file
|
@ -0,0 +1 @@
|
|||
(\d{2}\s\w*\s\d{4})\s+at\s+(\d{2}:\d{2}):\s+(.*)
|
35
route_guide/README.md
Normal file
35
route_guide/README.md
Normal file
|
@ -0,0 +1,35 @@
|
|||
# Description
|
||||
The route guide server and client demonstrate how to use grpc go libraries to
|
||||
perform unary, client streaming, server streaming and full duplex RPCs.
|
||||
|
||||
Please refer to [gRPC Basics: Go](https://grpc.io/docs/tutorials/basic/go.html) for more information.
|
||||
|
||||
See the definition of the route guide service in `routeguide/route_guide.proto`.
|
||||
|
||||
# Run the sample code
|
||||
To compile and run the server, assuming you are in the root of the `route_guide`
|
||||
folder, i.e., `.../examples/route_guide/`, simply:
|
||||
|
||||
```sh
|
||||
$ go run server/server.go
|
||||
```
|
||||
|
||||
Likewise, to run the client:
|
||||
|
||||
```sh
|
||||
$ go run client/client.go
|
||||
```
|
||||
|
||||
# Optional command line flags
|
||||
The server and client both take optional command line flags. For example, the
|
||||
client and server run without TLS by default. To enable TLS:
|
||||
|
||||
```sh
|
||||
$ go run server/server.go -tls=true
|
||||
```
|
||||
|
||||
and
|
||||
|
||||
```sh
|
||||
$ go run client/client.go -tls=true
|
||||
```
|
195
route_guide/client/client.go
Normal file
195
route_guide/client/client.go
Normal file
|
@ -0,0 +1,195 @@
|
|||
/*
|
||||
*
|
||||
* Copyright 2015 gRPC authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
// Package main implements a simple gRPC client that demonstrates how to use gRPC-Go libraries
|
||||
// to perform unary, client streaming, server streaming and full duplex RPCs.
|
||||
//
|
||||
// It interacts with the route guide service whose definition can be found in routeguide/route_guide.proto.
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"io"
|
||||
"log"
|
||||
"math/rand"
|
||||
"time"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
"google.golang.org/grpc/examples/data"
|
||||
pb "google.golang.org/grpc/examples/route_guide/routeguide"
|
||||
)
|
||||
|
||||
var (
|
||||
tls = flag.Bool("tls", false, "Connection uses TLS if true, else plain TCP")
|
||||
caFile = flag.String("ca_file", "", "The file containing the CA root cert file")
|
||||
serverAddr = flag.String("addr", "localhost:50051", "The server address in the format of host:port")
|
||||
serverHostOverride = flag.String("server_host_override", "x.test.example.com", "The server name used to verify the hostname returned by the TLS handshake")
|
||||
)
|
||||
|
||||
// printFeature gets the feature for the given point.
|
||||
func printFeature(client pb.RouteGuideClient, point *pb.Point) {
|
||||
log.Printf("Getting feature for point (%d, %d)", point.Latitude, point.Longitude)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
defer cancel()
|
||||
feature, err := client.GetFeature(ctx, point)
|
||||
if err != nil {
|
||||
log.Fatalf("client.GetFeature failed: %v", err)
|
||||
}
|
||||
log.Println(feature)
|
||||
}
|
||||
|
||||
// printFeatures lists all the features within the given bounding Rectangle.
|
||||
func printFeatures(client pb.RouteGuideClient, rect *pb.Rectangle) {
|
||||
log.Printf("Looking for features within %v", rect)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
defer cancel()
|
||||
stream, err := client.ListFeatures(ctx, rect)
|
||||
if err != nil {
|
||||
log.Fatalf("client.ListFeatures failed: %v", err)
|
||||
}
|
||||
for {
|
||||
feature, err := stream.Recv()
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
log.Fatalf("client.ListFeatures failed: %v", err)
|
||||
}
|
||||
log.Printf("Feature: name: %q, point:(%v, %v)", feature.GetName(),
|
||||
feature.GetLocation().GetLatitude(), feature.GetLocation().GetLongitude())
|
||||
}
|
||||
}
|
||||
|
||||
// runRecordRoute sends a sequence of points to server and expects to get a RouteSummary from server.
|
||||
func runRecordRoute(client pb.RouteGuideClient) {
|
||||
// Create a random number of random points
|
||||
r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||
pointCount := int(r.Int31n(100)) + 2 // Traverse at least two points
|
||||
var points []*pb.Point
|
||||
for i := 0; i < pointCount; i++ {
|
||||
points = append(points, randomPoint(r))
|
||||
}
|
||||
log.Printf("Traversing %d points.", len(points))
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
defer cancel()
|
||||
stream, err := client.RecordRoute(ctx)
|
||||
if err != nil {
|
||||
log.Fatalf("client.RecordRoute failed: %v", err)
|
||||
}
|
||||
for _, point := range points {
|
||||
if err := stream.Send(point); err != nil {
|
||||
log.Fatalf("client.RecordRoute: stream.Send(%v) failed: %v", point, err)
|
||||
}
|
||||
}
|
||||
reply, err := stream.CloseAndRecv()
|
||||
if err != nil {
|
||||
log.Fatalf("client.RecordRoute failed: %v", err)
|
||||
}
|
||||
log.Printf("Route summary: %v", reply)
|
||||
}
|
||||
|
||||
// runRouteChat receives a sequence of route notes, while sending notes for various locations.
|
||||
func runRouteChat(client pb.RouteGuideClient) {
|
||||
notes := []*pb.RouteNote{
|
||||
{Location: &pb.Point{Latitude: 0, Longitude: 1}, Message: "First message"},
|
||||
{Location: &pb.Point{Latitude: 0, Longitude: 2}, Message: "Second message"},
|
||||
{Location: &pb.Point{Latitude: 0, Longitude: 3}, Message: "Third message"},
|
||||
{Location: &pb.Point{Latitude: 0, Longitude: 1}, Message: "Fourth message"},
|
||||
{Location: &pb.Point{Latitude: 0, Longitude: 2}, Message: "Fifth message"},
|
||||
{Location: &pb.Point{Latitude: 0, Longitude: 3}, Message: "Sixth message"},
|
||||
}
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
defer cancel()
|
||||
stream, err := client.RouteChat(ctx)
|
||||
if err != nil {
|
||||
log.Fatalf("client.RouteChat failed: %v", err)
|
||||
}
|
||||
waitc := make(chan struct{})
|
||||
go func() {
|
||||
for {
|
||||
in, err := stream.Recv()
|
||||
if err == io.EOF {
|
||||
// read done.
|
||||
close(waitc)
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
log.Fatalf("client.RouteChat failed: %v", err)
|
||||
}
|
||||
log.Printf("Got message %s at point(%d, %d)", in.Message, in.Location.Latitude, in.Location.Longitude)
|
||||
}
|
||||
}()
|
||||
for _, note := range notes {
|
||||
if err := stream.Send(note); err != nil {
|
||||
log.Fatalf("client.RouteChat: stream.Send(%v) failed: %v", note, err)
|
||||
}
|
||||
}
|
||||
stream.CloseSend()
|
||||
<-waitc
|
||||
}
|
||||
|
||||
func randomPoint(r *rand.Rand) *pb.Point {
|
||||
lat := (r.Int31n(180) - 90) * 1e7
|
||||
long := (r.Int31n(360) - 180) * 1e7
|
||||
return &pb.Point{Latitude: lat, Longitude: long}
|
||||
}
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
var opts []grpc.DialOption
|
||||
if *tls {
|
||||
if *caFile == "" {
|
||||
*caFile = data.Path("x509/ca_cert.pem")
|
||||
}
|
||||
creds, err := credentials.NewClientTLSFromFile(*caFile, *serverHostOverride)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to create TLS credentials: %v", err)
|
||||
}
|
||||
opts = append(opts, grpc.WithTransportCredentials(creds))
|
||||
} else {
|
||||
opts = append(opts, grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
}
|
||||
|
||||
conn, err := grpc.Dial(*serverAddr, opts...)
|
||||
if err != nil {
|
||||
log.Fatalf("fail to dial: %v", err)
|
||||
}
|
||||
defer conn.Close()
|
||||
client := pb.NewRouteGuideClient(conn)
|
||||
|
||||
// Looking for a valid feature
|
||||
printFeature(client, &pb.Point{Latitude: 409146138, Longitude: -746188906})
|
||||
|
||||
// Feature missing.
|
||||
printFeature(client, &pb.Point{Latitude: 0, Longitude: 0})
|
||||
|
||||
// Looking for features between 40, -75 and 42, -73.
|
||||
printFeatures(client, &pb.Rectangle{
|
||||
Lo: &pb.Point{Latitude: 400000000, Longitude: -750000000},
|
||||
Hi: &pb.Point{Latitude: 420000000, Longitude: -730000000},
|
||||
})
|
||||
|
||||
// RecordRoute
|
||||
runRecordRoute(client)
|
||||
|
||||
// RouteChat
|
||||
runRouteChat(client)
|
||||
}
|
540
route_guide/routeguide/route_guide.pb.go
Normal file
540
route_guide/routeguide/route_guide.pb.go
Normal file
|
@ -0,0 +1,540 @@
|
|||
// Copyright 2015 gRPC authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.32.0
|
||||
// protoc v4.25.2
|
||||
// source: examples/route_guide/routeguide/route_guide.proto
|
||||
|
||||
package routeguide
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
// Points are represented as latitude-longitude pairs in the E7 representation
|
||||
// (degrees multiplied by 10**7 and rounded to the nearest integer).
|
||||
// Latitudes should be in the range +/- 90 degrees and longitude should be in
|
||||
// the range +/- 180 degrees (inclusive).
|
||||
type Point struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Latitude int32 `protobuf:"varint,1,opt,name=latitude,proto3" json:"latitude,omitempty"`
|
||||
Longitude int32 `protobuf:"varint,2,opt,name=longitude,proto3" json:"longitude,omitempty"`
|
||||
}
|
||||
|
||||
func (x *Point) Reset() {
|
||||
*x = Point{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_examples_route_guide_routeguide_route_guide_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Point) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Point) ProtoMessage() {}
|
||||
|
||||
func (x *Point) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_examples_route_guide_routeguide_route_guide_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Point.ProtoReflect.Descriptor instead.
|
||||
func (*Point) Descriptor() ([]byte, []int) {
|
||||
return file_examples_route_guide_routeguide_route_guide_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *Point) GetLatitude() int32 {
|
||||
if x != nil {
|
||||
return x.Latitude
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *Point) GetLongitude() int32 {
|
||||
if x != nil {
|
||||
return x.Longitude
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// A latitude-longitude rectangle, represented as two diagonally opposite
|
||||
// points "lo" and "hi".
|
||||
type Rectangle struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
// One corner of the rectangle.
|
||||
Lo *Point `protobuf:"bytes,1,opt,name=lo,proto3" json:"lo,omitempty"`
|
||||
// The other corner of the rectangle.
|
||||
Hi *Point `protobuf:"bytes,2,opt,name=hi,proto3" json:"hi,omitempty"`
|
||||
}
|
||||
|
||||
func (x *Rectangle) Reset() {
|
||||
*x = Rectangle{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_examples_route_guide_routeguide_route_guide_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Rectangle) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Rectangle) ProtoMessage() {}
|
||||
|
||||
func (x *Rectangle) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_examples_route_guide_routeguide_route_guide_proto_msgTypes[1]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Rectangle.ProtoReflect.Descriptor instead.
|
||||
func (*Rectangle) Descriptor() ([]byte, []int) {
|
||||
return file_examples_route_guide_routeguide_route_guide_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *Rectangle) GetLo() *Point {
|
||||
if x != nil {
|
||||
return x.Lo
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Rectangle) GetHi() *Point {
|
||||
if x != nil {
|
||||
return x.Hi
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// A feature names something at a given point.
|
||||
//
|
||||
// If a feature could not be named, the name is empty.
|
||||
type Feature struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
// The name of the feature.
|
||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||
// The point where the feature is detected.
|
||||
Location *Point `protobuf:"bytes,2,opt,name=location,proto3" json:"location,omitempty"`
|
||||
}
|
||||
|
||||
func (x *Feature) Reset() {
|
||||
*x = Feature{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_examples_route_guide_routeguide_route_guide_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Feature) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Feature) ProtoMessage() {}
|
||||
|
||||
func (x *Feature) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_examples_route_guide_routeguide_route_guide_proto_msgTypes[2]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Feature.ProtoReflect.Descriptor instead.
|
||||
func (*Feature) Descriptor() ([]byte, []int) {
|
||||
return file_examples_route_guide_routeguide_route_guide_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (x *Feature) GetName() string {
|
||||
if x != nil {
|
||||
return x.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Feature) GetLocation() *Point {
|
||||
if x != nil {
|
||||
return x.Location
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// A RouteNote is a message sent while at a given point.
|
||||
type RouteNote struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
// The location from which the message is sent.
|
||||
Location *Point `protobuf:"bytes,1,opt,name=location,proto3" json:"location,omitempty"`
|
||||
// The message to be sent.
|
||||
Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"`
|
||||
}
|
||||
|
||||
func (x *RouteNote) Reset() {
|
||||
*x = RouteNote{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_examples_route_guide_routeguide_route_guide_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *RouteNote) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*RouteNote) ProtoMessage() {}
|
||||
|
||||
func (x *RouteNote) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_examples_route_guide_routeguide_route_guide_proto_msgTypes[3]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use RouteNote.ProtoReflect.Descriptor instead.
|
||||
func (*RouteNote) Descriptor() ([]byte, []int) {
|
||||
return file_examples_route_guide_routeguide_route_guide_proto_rawDescGZIP(), []int{3}
|
||||
}
|
||||
|
||||
func (x *RouteNote) GetLocation() *Point {
|
||||
if x != nil {
|
||||
return x.Location
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *RouteNote) GetMessage() string {
|
||||
if x != nil {
|
||||
return x.Message
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// A RouteSummary is received in response to a RecordRoute rpc.
|
||||
//
|
||||
// It contains the number of individual points received, the number of
|
||||
// detected features, and the total distance covered as the cumulative sum of
|
||||
// the distance between each point.
|
||||
type RouteSummary struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
// The number of points received.
|
||||
PointCount int32 `protobuf:"varint,1,opt,name=point_count,json=pointCount,proto3" json:"point_count,omitempty"`
|
||||
// The number of known features passed while traversing the route.
|
||||
FeatureCount int32 `protobuf:"varint,2,opt,name=feature_count,json=featureCount,proto3" json:"feature_count,omitempty"`
|
||||
// The distance covered in metres.
|
||||
Distance int32 `protobuf:"varint,3,opt,name=distance,proto3" json:"distance,omitempty"`
|
||||
// The duration of the traversal in seconds.
|
||||
ElapsedTime int32 `protobuf:"varint,4,opt,name=elapsed_time,json=elapsedTime,proto3" json:"elapsed_time,omitempty"`
|
||||
}
|
||||
|
||||
func (x *RouteSummary) Reset() {
|
||||
*x = RouteSummary{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_examples_route_guide_routeguide_route_guide_proto_msgTypes[4]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *RouteSummary) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*RouteSummary) ProtoMessage() {}
|
||||
|
||||
func (x *RouteSummary) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_examples_route_guide_routeguide_route_guide_proto_msgTypes[4]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use RouteSummary.ProtoReflect.Descriptor instead.
|
||||
func (*RouteSummary) Descriptor() ([]byte, []int) {
|
||||
return file_examples_route_guide_routeguide_route_guide_proto_rawDescGZIP(), []int{4}
|
||||
}
|
||||
|
||||
func (x *RouteSummary) GetPointCount() int32 {
|
||||
if x != nil {
|
||||
return x.PointCount
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *RouteSummary) GetFeatureCount() int32 {
|
||||
if x != nil {
|
||||
return x.FeatureCount
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *RouteSummary) GetDistance() int32 {
|
||||
if x != nil {
|
||||
return x.Distance
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *RouteSummary) GetElapsedTime() int32 {
|
||||
if x != nil {
|
||||
return x.ElapsedTime
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
var File_examples_route_guide_routeguide_route_guide_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_examples_route_guide_routeguide_route_guide_proto_rawDesc = []byte{
|
||||
0x0a, 0x31, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2f, 0x72, 0x6f, 0x75, 0x74, 0x65,
|
||||
0x5f, 0x67, 0x75, 0x69, 0x64, 0x65, 0x2f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x67, 0x75, 0x69, 0x64,
|
||||
0x65, 0x2f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x5f, 0x67, 0x75, 0x69, 0x64, 0x65, 0x2e, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x12, 0x0a, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x67, 0x75, 0x69, 0x64, 0x65, 0x22,
|
||||
0x41, 0x0a, 0x05, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x61, 0x74, 0x69,
|
||||
0x74, 0x75, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x6c, 0x61, 0x74, 0x69,
|
||||
0x74, 0x75, 0x64, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6c, 0x6f, 0x6e, 0x67, 0x69, 0x74, 0x75, 0x64,
|
||||
0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x6c, 0x6f, 0x6e, 0x67, 0x69, 0x74, 0x75,
|
||||
0x64, 0x65, 0x22, 0x51, 0x0a, 0x09, 0x52, 0x65, 0x63, 0x74, 0x61, 0x6e, 0x67, 0x6c, 0x65, 0x12,
|
||||
0x21, 0x0a, 0x02, 0x6c, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x72, 0x6f,
|
||||
0x75, 0x74, 0x65, 0x67, 0x75, 0x69, 0x64, 0x65, 0x2e, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x02,
|
||||
0x6c, 0x6f, 0x12, 0x21, 0x0a, 0x02, 0x68, 0x69, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11,
|
||||
0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x67, 0x75, 0x69, 0x64, 0x65, 0x2e, 0x50, 0x6f, 0x69, 0x6e,
|
||||
0x74, 0x52, 0x02, 0x68, 0x69, 0x22, 0x4c, 0x0a, 0x07, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65,
|
||||
0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
|
||||
0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2d, 0x0a, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x67, 0x75,
|
||||
0x69, 0x64, 0x65, 0x2e, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74,
|
||||
0x69, 0x6f, 0x6e, 0x22, 0x54, 0x0a, 0x09, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x4e, 0x6f, 0x74, 0x65,
|
||||
0x12, 0x2d, 0x0a, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x0b, 0x32, 0x11, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x67, 0x75, 0x69, 0x64, 0x65, 0x2e,
|
||||
0x50, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12,
|
||||
0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x93, 0x01, 0x0a, 0x0c, 0x52, 0x6f,
|
||||
0x75, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x6f,
|
||||
0x69, 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52,
|
||||
0x0a, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x66,
|
||||
0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01,
|
||||
0x28, 0x05, 0x52, 0x0c, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74,
|
||||
0x12, 0x1a, 0x0a, 0x08, 0x64, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01,
|
||||
0x28, 0x05, 0x52, 0x08, 0x64, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x21, 0x0a, 0x0c,
|
||||
0x65, 0x6c, 0x61, 0x70, 0x73, 0x65, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01,
|
||||
0x28, 0x05, 0x52, 0x0b, 0x65, 0x6c, 0x61, 0x70, 0x73, 0x65, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x32,
|
||||
0x85, 0x02, 0x0a, 0x0a, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x47, 0x75, 0x69, 0x64, 0x65, 0x12, 0x36,
|
||||
0x0a, 0x0a, 0x47, 0x65, 0x74, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x11, 0x2e, 0x72,
|
||||
0x6f, 0x75, 0x74, 0x65, 0x67, 0x75, 0x69, 0x64, 0x65, 0x2e, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x1a,
|
||||
0x13, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x67, 0x75, 0x69, 0x64, 0x65, 0x2e, 0x46, 0x65, 0x61,
|
||||
0x74, 0x75, 0x72, 0x65, 0x22, 0x00, 0x12, 0x3e, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x65,
|
||||
0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, 0x15, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x67, 0x75,
|
||||
0x69, 0x64, 0x65, 0x2e, 0x52, 0x65, 0x63, 0x74, 0x61, 0x6e, 0x67, 0x6c, 0x65, 0x1a, 0x13, 0x2e,
|
||||
0x72, 0x6f, 0x75, 0x74, 0x65, 0x67, 0x75, 0x69, 0x64, 0x65, 0x2e, 0x46, 0x65, 0x61, 0x74, 0x75,
|
||||
0x72, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x3e, 0x0a, 0x0b, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64,
|
||||
0x52, 0x6f, 0x75, 0x74, 0x65, 0x12, 0x11, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x67, 0x75, 0x69,
|
||||
0x64, 0x65, 0x2e, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x1a, 0x18, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65,
|
||||
0x67, 0x75, 0x69, 0x64, 0x65, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61,
|
||||
0x72, 0x79, 0x22, 0x00, 0x28, 0x01, 0x12, 0x3f, 0x0a, 0x09, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x43,
|
||||
0x68, 0x61, 0x74, 0x12, 0x15, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x67, 0x75, 0x69, 0x64, 0x65,
|
||||
0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x4e, 0x6f, 0x74, 0x65, 0x1a, 0x15, 0x2e, 0x72, 0x6f, 0x75,
|
||||
0x74, 0x65, 0x67, 0x75, 0x69, 0x64, 0x65, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x4e, 0x6f, 0x74,
|
||||
0x65, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x42, 0x68, 0x0a, 0x1b, 0x69, 0x6f, 0x2e, 0x67, 0x72,
|
||||
0x70, 0x63, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2e, 0x72, 0x6f, 0x75, 0x74,
|
||||
0x65, 0x67, 0x75, 0x69, 0x64, 0x65, 0x42, 0x0f, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x47, 0x75, 0x69,
|
||||
0x64, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x36, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
|
||||
0x65, 0x2e, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x72, 0x70,
|
||||
0x63, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2f, 0x72, 0x6f, 0x75, 0x74, 0x65,
|
||||
0x5f, 0x67, 0x75, 0x69, 0x64, 0x65, 0x2f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x67, 0x75, 0x69, 0x64,
|
||||
0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
file_examples_route_guide_routeguide_route_guide_proto_rawDescOnce sync.Once
|
||||
file_examples_route_guide_routeguide_route_guide_proto_rawDescData = file_examples_route_guide_routeguide_route_guide_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_examples_route_guide_routeguide_route_guide_proto_rawDescGZIP() []byte {
|
||||
file_examples_route_guide_routeguide_route_guide_proto_rawDescOnce.Do(func() {
|
||||
file_examples_route_guide_routeguide_route_guide_proto_rawDescData = protoimpl.X.CompressGZIP(file_examples_route_guide_routeguide_route_guide_proto_rawDescData)
|
||||
})
|
||||
return file_examples_route_guide_routeguide_route_guide_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_examples_route_guide_routeguide_route_guide_proto_msgTypes = make([]protoimpl.MessageInfo, 5)
|
||||
var file_examples_route_guide_routeguide_route_guide_proto_goTypes = []interface{}{
|
||||
(*Point)(nil), // 0: routeguide.Point
|
||||
(*Rectangle)(nil), // 1: routeguide.Rectangle
|
||||
(*Feature)(nil), // 2: routeguide.Feature
|
||||
(*RouteNote)(nil), // 3: routeguide.RouteNote
|
||||
(*RouteSummary)(nil), // 4: routeguide.RouteSummary
|
||||
}
|
||||
var file_examples_route_guide_routeguide_route_guide_proto_depIdxs = []int32{
|
||||
0, // 0: routeguide.Rectangle.lo:type_name -> routeguide.Point
|
||||
0, // 1: routeguide.Rectangle.hi:type_name -> routeguide.Point
|
||||
0, // 2: routeguide.Feature.location:type_name -> routeguide.Point
|
||||
0, // 3: routeguide.RouteNote.location:type_name -> routeguide.Point
|
||||
0, // 4: routeguide.RouteGuide.GetFeature:input_type -> routeguide.Point
|
||||
1, // 5: routeguide.RouteGuide.ListFeatures:input_type -> routeguide.Rectangle
|
||||
0, // 6: routeguide.RouteGuide.RecordRoute:input_type -> routeguide.Point
|
||||
3, // 7: routeguide.RouteGuide.RouteChat:input_type -> routeguide.RouteNote
|
||||
2, // 8: routeguide.RouteGuide.GetFeature:output_type -> routeguide.Feature
|
||||
2, // 9: routeguide.RouteGuide.ListFeatures:output_type -> routeguide.Feature
|
||||
4, // 10: routeguide.RouteGuide.RecordRoute:output_type -> routeguide.RouteSummary
|
||||
3, // 11: routeguide.RouteGuide.RouteChat:output_type -> routeguide.RouteNote
|
||||
8, // [8:12] is the sub-list for method output_type
|
||||
4, // [4:8] is the sub-list for method input_type
|
||||
4, // [4:4] is the sub-list for extension type_name
|
||||
4, // [4:4] is the sub-list for extension extendee
|
||||
0, // [0:4] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_examples_route_guide_routeguide_route_guide_proto_init() }
|
||||
func file_examples_route_guide_routeguide_route_guide_proto_init() {
|
||||
if File_examples_route_guide_routeguide_route_guide_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_examples_route_guide_routeguide_route_guide_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Point); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_examples_route_guide_routeguide_route_guide_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Rectangle); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_examples_route_guide_routeguide_route_guide_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Feature); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_examples_route_guide_routeguide_route_guide_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*RouteNote); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_examples_route_guide_routeguide_route_guide_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*RouteSummary); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_examples_route_guide_routeguide_route_guide_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 5,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
GoTypes: file_examples_route_guide_routeguide_route_guide_proto_goTypes,
|
||||
DependencyIndexes: file_examples_route_guide_routeguide_route_guide_proto_depIdxs,
|
||||
MessageInfos: file_examples_route_guide_routeguide_route_guide_proto_msgTypes,
|
||||
}.Build()
|
||||
File_examples_route_guide_routeguide_route_guide_proto = out.File
|
||||
file_examples_route_guide_routeguide_route_guide_proto_rawDesc = nil
|
||||
file_examples_route_guide_routeguide_route_guide_proto_goTypes = nil
|
||||
file_examples_route_guide_routeguide_route_guide_proto_depIdxs = nil
|
||||
}
|
111
route_guide/routeguide/route_guide.proto
Normal file
111
route_guide/routeguide/route_guide.proto
Normal file
|
@ -0,0 +1,111 @@
|
|||
// Copyright 2015 gRPC authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
option go_package = "go_sandbox/route_guide/routeguide";
|
||||
option java_multiple_files = true;
|
||||
option java_package = "io.grpc.examples.routeguide";
|
||||
option java_outer_classname = "RouteGuideProto";
|
||||
|
||||
package routeguide;
|
||||
|
||||
// Interface exported by the server.
|
||||
service RouteGuide {
|
||||
// A simple RPC.
|
||||
//
|
||||
// Obtains the feature at a given position.
|
||||
//
|
||||
// A feature with an empty name is returned if there's no feature at the given
|
||||
// position.
|
||||
rpc GetFeature(Point) returns (Feature) {}
|
||||
|
||||
// A server-to-client streaming RPC.
|
||||
//
|
||||
// Obtains the Features available within the given Rectangle. Results are
|
||||
// streamed rather than returned at once (e.g. in a response message with a
|
||||
// repeated field), as the rectangle may cover a large area and contain a
|
||||
// huge number of features.
|
||||
rpc ListFeatures(Rectangle) returns (stream Feature) {}
|
||||
|
||||
// A client-to-server streaming RPC.
|
||||
//
|
||||
// Accepts a stream of Points on a route being traversed, returning a
|
||||
// RouteSummary when traversal is completed.
|
||||
rpc RecordRoute(stream Point) returns (RouteSummary) {}
|
||||
|
||||
// A Bidirectional streaming RPC.
|
||||
//
|
||||
// Accepts a stream of RouteNotes sent while a route is being traversed,
|
||||
// while receiving other RouteNotes (e.g. from other users).
|
||||
rpc RouteChat(stream RouteNote) returns (stream RouteNote) {}
|
||||
}
|
||||
|
||||
// Points are represented as latitude-longitude pairs in the E7 representation
|
||||
// (degrees multiplied by 10**7 and rounded to the nearest integer).
|
||||
// Latitudes should be in the range +/- 90 degrees and longitude should be in
|
||||
// the range +/- 180 degrees (inclusive).
|
||||
message Point {
|
||||
int32 latitude = 1;
|
||||
int32 longitude = 2;
|
||||
}
|
||||
|
||||
// A latitude-longitude rectangle, represented as two diagonally opposite
|
||||
// points "lo" and "hi".
|
||||
message Rectangle {
|
||||
// One corner of the rectangle.
|
||||
Point lo = 1;
|
||||
|
||||
// The other corner of the rectangle.
|
||||
Point hi = 2;
|
||||
}
|
||||
|
||||
// A feature names something at a given point.
|
||||
//
|
||||
// If a feature could not be named, the name is empty.
|
||||
message Feature {
|
||||
// The name of the feature.
|
||||
string name = 1;
|
||||
|
||||
// The point where the feature is detected.
|
||||
Point location = 2;
|
||||
}
|
||||
|
||||
// A RouteNote is a message sent while at a given point.
|
||||
message RouteNote {
|
||||
// The location from which the message is sent.
|
||||
Point location = 1;
|
||||
|
||||
// The message to be sent.
|
||||
string message = 2;
|
||||
}
|
||||
|
||||
// A RouteSummary is received in response to a RecordRoute rpc.
|
||||
//
|
||||
// It contains the number of individual points received, the number of
|
||||
// detected features, and the total distance covered as the cumulative sum of
|
||||
// the distance between each point.
|
||||
message RouteSummary {
|
||||
// The number of points received.
|
||||
int32 point_count = 1;
|
||||
|
||||
// The number of known features passed while traversing the route.
|
||||
int32 feature_count = 2;
|
||||
|
||||
// The distance covered in metres.
|
||||
int32 distance = 3;
|
||||
|
||||
// The duration of the traversal in seconds.
|
||||
int32 elapsed_time = 4;
|
||||
}
|
368
route_guide/routeguide/route_guide_grpc.pb.go
Normal file
368
route_guide/routeguide/route_guide_grpc.pb.go
Normal file
|
@ -0,0 +1,368 @@
|
|||
// Copyright 2015 gRPC authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||
// versions:
|
||||
// - protoc-gen-go-grpc v1.3.0
|
||||
// - protoc v4.25.2
|
||||
// source: examples/route_guide/routeguide/route_guide.proto
|
||||
|
||||
package routeguide
|
||||
|
||||
import (
|
||||
context "context"
|
||||
grpc "google.golang.org/grpc"
|
||||
codes "google.golang.org/grpc/codes"
|
||||
status "google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the grpc package it is being compiled against.
|
||||
// Requires gRPC-Go v1.32.0 or later.
|
||||
const _ = grpc.SupportPackageIsVersion7
|
||||
|
||||
const (
|
||||
RouteGuide_GetFeature_FullMethodName = "/routeguide.RouteGuide/GetFeature"
|
||||
RouteGuide_ListFeatures_FullMethodName = "/routeguide.RouteGuide/ListFeatures"
|
||||
RouteGuide_RecordRoute_FullMethodName = "/routeguide.RouteGuide/RecordRoute"
|
||||
RouteGuide_RouteChat_FullMethodName = "/routeguide.RouteGuide/RouteChat"
|
||||
)
|
||||
|
||||
// RouteGuideClient is the client API for RouteGuide service.
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
||||
type RouteGuideClient interface {
|
||||
// A simple RPC.
|
||||
//
|
||||
// Obtains the feature at a given position.
|
||||
//
|
||||
// A feature with an empty name is returned if there's no feature at the given
|
||||
// position.
|
||||
GetFeature(ctx context.Context, in *Point, opts ...grpc.CallOption) (*Feature, error)
|
||||
// A server-to-client streaming RPC.
|
||||
//
|
||||
// Obtains the Features available within the given Rectangle. Results are
|
||||
// streamed rather than returned at once (e.g. in a response message with a
|
||||
// repeated field), as the rectangle may cover a large area and contain a
|
||||
// huge number of features.
|
||||
ListFeatures(ctx context.Context, in *Rectangle, opts ...grpc.CallOption) (RouteGuide_ListFeaturesClient, error)
|
||||
// A client-to-server streaming RPC.
|
||||
//
|
||||
// Accepts a stream of Points on a route being traversed, returning a
|
||||
// RouteSummary when traversal is completed.
|
||||
RecordRoute(ctx context.Context, opts ...grpc.CallOption) (RouteGuide_RecordRouteClient, error)
|
||||
// A Bidirectional streaming RPC.
|
||||
//
|
||||
// Accepts a stream of RouteNotes sent while a route is being traversed,
|
||||
// while receiving other RouteNotes (e.g. from other users).
|
||||
RouteChat(ctx context.Context, opts ...grpc.CallOption) (RouteGuide_RouteChatClient, error)
|
||||
}
|
||||
|
||||
type routeGuideClient struct {
|
||||
cc grpc.ClientConnInterface
|
||||
}
|
||||
|
||||
func NewRouteGuideClient(cc grpc.ClientConnInterface) RouteGuideClient {
|
||||
return &routeGuideClient{cc}
|
||||
}
|
||||
|
||||
func (c *routeGuideClient) GetFeature(ctx context.Context, in *Point, opts ...grpc.CallOption) (*Feature, error) {
|
||||
out := new(Feature)
|
||||
err := c.cc.Invoke(ctx, RouteGuide_GetFeature_FullMethodName, in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *routeGuideClient) ListFeatures(ctx context.Context, in *Rectangle, opts ...grpc.CallOption) (RouteGuide_ListFeaturesClient, error) {
|
||||
stream, err := c.cc.NewStream(ctx, &RouteGuide_ServiceDesc.Streams[0], RouteGuide_ListFeatures_FullMethodName, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
x := &routeGuideListFeaturesClient{stream}
|
||||
if err := x.ClientStream.SendMsg(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := x.ClientStream.CloseSend(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return x, nil
|
||||
}
|
||||
|
||||
type RouteGuide_ListFeaturesClient interface {
|
||||
Recv() (*Feature, error)
|
||||
grpc.ClientStream
|
||||
}
|
||||
|
||||
type routeGuideListFeaturesClient struct {
|
||||
grpc.ClientStream
|
||||
}
|
||||
|
||||
func (x *routeGuideListFeaturesClient) Recv() (*Feature, error) {
|
||||
m := new(Feature)
|
||||
if err := x.ClientStream.RecvMsg(m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func (c *routeGuideClient) RecordRoute(ctx context.Context, opts ...grpc.CallOption) (RouteGuide_RecordRouteClient, error) {
|
||||
stream, err := c.cc.NewStream(ctx, &RouteGuide_ServiceDesc.Streams[1], RouteGuide_RecordRoute_FullMethodName, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
x := &routeGuideRecordRouteClient{stream}
|
||||
return x, nil
|
||||
}
|
||||
|
||||
type RouteGuide_RecordRouteClient interface {
|
||||
Send(*Point) error
|
||||
CloseAndRecv() (*RouteSummary, error)
|
||||
grpc.ClientStream
|
||||
}
|
||||
|
||||
type routeGuideRecordRouteClient struct {
|
||||
grpc.ClientStream
|
||||
}
|
||||
|
||||
func (x *routeGuideRecordRouteClient) Send(m *Point) error {
|
||||
return x.ClientStream.SendMsg(m)
|
||||
}
|
||||
|
||||
func (x *routeGuideRecordRouteClient) CloseAndRecv() (*RouteSummary, error) {
|
||||
if err := x.ClientStream.CloseSend(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
m := new(RouteSummary)
|
||||
if err := x.ClientStream.RecvMsg(m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func (c *routeGuideClient) RouteChat(ctx context.Context, opts ...grpc.CallOption) (RouteGuide_RouteChatClient, error) {
|
||||
stream, err := c.cc.NewStream(ctx, &RouteGuide_ServiceDesc.Streams[2], RouteGuide_RouteChat_FullMethodName, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
x := &routeGuideRouteChatClient{stream}
|
||||
return x, nil
|
||||
}
|
||||
|
||||
type RouteGuide_RouteChatClient interface {
|
||||
Send(*RouteNote) error
|
||||
Recv() (*RouteNote, error)
|
||||
grpc.ClientStream
|
||||
}
|
||||
|
||||
type routeGuideRouteChatClient struct {
|
||||
grpc.ClientStream
|
||||
}
|
||||
|
||||
func (x *routeGuideRouteChatClient) Send(m *RouteNote) error {
|
||||
return x.ClientStream.SendMsg(m)
|
||||
}
|
||||
|
||||
func (x *routeGuideRouteChatClient) Recv() (*RouteNote, error) {
|
||||
m := new(RouteNote)
|
||||
if err := x.ClientStream.RecvMsg(m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// RouteGuideServer is the server API for RouteGuide service.
|
||||
// All implementations must embed UnimplementedRouteGuideServer
|
||||
// for forward compatibility
|
||||
type RouteGuideServer interface {
|
||||
// A simple RPC.
|
||||
//
|
||||
// Obtains the feature at a given position.
|
||||
//
|
||||
// A feature with an empty name is returned if there's no feature at the given
|
||||
// position.
|
||||
GetFeature(context.Context, *Point) (*Feature, error)
|
||||
// A server-to-client streaming RPC.
|
||||
//
|
||||
// Obtains the Features available within the given Rectangle. Results are
|
||||
// streamed rather than returned at once (e.g. in a response message with a
|
||||
// repeated field), as the rectangle may cover a large area and contain a
|
||||
// huge number of features.
|
||||
ListFeatures(*Rectangle, RouteGuide_ListFeaturesServer) error
|
||||
// A client-to-server streaming RPC.
|
||||
//
|
||||
// Accepts a stream of Points on a route being traversed, returning a
|
||||
// RouteSummary when traversal is completed.
|
||||
RecordRoute(RouteGuide_RecordRouteServer) error
|
||||
// A Bidirectional streaming RPC.
|
||||
//
|
||||
// Accepts a stream of RouteNotes sent while a route is being traversed,
|
||||
// while receiving other RouteNotes (e.g. from other users).
|
||||
RouteChat(RouteGuide_RouteChatServer) error
|
||||
mustEmbedUnimplementedRouteGuideServer()
|
||||
}
|
||||
|
||||
// UnimplementedRouteGuideServer must be embedded to have forward compatible implementations.
|
||||
type UnimplementedRouteGuideServer struct {
|
||||
}
|
||||
|
||||
func (UnimplementedRouteGuideServer) GetFeature(context.Context, *Point) (*Feature, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetFeature not implemented")
|
||||
}
|
||||
func (UnimplementedRouteGuideServer) ListFeatures(*Rectangle, RouteGuide_ListFeaturesServer) error {
|
||||
return status.Errorf(codes.Unimplemented, "method ListFeatures not implemented")
|
||||
}
|
||||
func (UnimplementedRouteGuideServer) RecordRoute(RouteGuide_RecordRouteServer) error {
|
||||
return status.Errorf(codes.Unimplemented, "method RecordRoute not implemented")
|
||||
}
|
||||
func (UnimplementedRouteGuideServer) RouteChat(RouteGuide_RouteChatServer) error {
|
||||
return status.Errorf(codes.Unimplemented, "method RouteChat not implemented")
|
||||
}
|
||||
func (UnimplementedRouteGuideServer) mustEmbedUnimplementedRouteGuideServer() {}
|
||||
|
||||
// UnsafeRouteGuideServer may be embedded to opt out of forward compatibility for this service.
|
||||
// Use of this interface is not recommended, as added methods to RouteGuideServer will
|
||||
// result in compilation errors.
|
||||
type UnsafeRouteGuideServer interface {
|
||||
mustEmbedUnimplementedRouteGuideServer()
|
||||
}
|
||||
|
||||
func RegisterRouteGuideServer(s grpc.ServiceRegistrar, srv RouteGuideServer) {
|
||||
s.RegisterService(&RouteGuide_ServiceDesc, srv)
|
||||
}
|
||||
|
||||
func _RouteGuide_GetFeature_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(Point)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(RouteGuideServer).GetFeature(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: RouteGuide_GetFeature_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(RouteGuideServer).GetFeature(ctx, req.(*Point))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _RouteGuide_ListFeatures_Handler(srv interface{}, stream grpc.ServerStream) error {
|
||||
m := new(Rectangle)
|
||||
if err := stream.RecvMsg(m); err != nil {
|
||||
return err
|
||||
}
|
||||
return srv.(RouteGuideServer).ListFeatures(m, &routeGuideListFeaturesServer{stream})
|
||||
}
|
||||
|
||||
type RouteGuide_ListFeaturesServer interface {
|
||||
Send(*Feature) error
|
||||
grpc.ServerStream
|
||||
}
|
||||
|
||||
type routeGuideListFeaturesServer struct {
|
||||
grpc.ServerStream
|
||||
}
|
||||
|
||||
func (x *routeGuideListFeaturesServer) Send(m *Feature) error {
|
||||
return x.ServerStream.SendMsg(m)
|
||||
}
|
||||
|
||||
func _RouteGuide_RecordRoute_Handler(srv interface{}, stream grpc.ServerStream) error {
|
||||
return srv.(RouteGuideServer).RecordRoute(&routeGuideRecordRouteServer{stream})
|
||||
}
|
||||
|
||||
type RouteGuide_RecordRouteServer interface {
|
||||
SendAndClose(*RouteSummary) error
|
||||
Recv() (*Point, error)
|
||||
grpc.ServerStream
|
||||
}
|
||||
|
||||
type routeGuideRecordRouteServer struct {
|
||||
grpc.ServerStream
|
||||
}
|
||||
|
||||
func (x *routeGuideRecordRouteServer) SendAndClose(m *RouteSummary) error {
|
||||
return x.ServerStream.SendMsg(m)
|
||||
}
|
||||
|
||||
func (x *routeGuideRecordRouteServer) Recv() (*Point, error) {
|
||||
m := new(Point)
|
||||
if err := x.ServerStream.RecvMsg(m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func _RouteGuide_RouteChat_Handler(srv interface{}, stream grpc.ServerStream) error {
|
||||
return srv.(RouteGuideServer).RouteChat(&routeGuideRouteChatServer{stream})
|
||||
}
|
||||
|
||||
type RouteGuide_RouteChatServer interface {
|
||||
Send(*RouteNote) error
|
||||
Recv() (*RouteNote, error)
|
||||
grpc.ServerStream
|
||||
}
|
||||
|
||||
type routeGuideRouteChatServer struct {
|
||||
grpc.ServerStream
|
||||
}
|
||||
|
||||
func (x *routeGuideRouteChatServer) Send(m *RouteNote) error {
|
||||
return x.ServerStream.SendMsg(m)
|
||||
}
|
||||
|
||||
func (x *routeGuideRouteChatServer) Recv() (*RouteNote, error) {
|
||||
m := new(RouteNote)
|
||||
if err := x.ServerStream.RecvMsg(m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// RouteGuide_ServiceDesc is the grpc.ServiceDesc for RouteGuide service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
var RouteGuide_ServiceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "routeguide.RouteGuide",
|
||||
HandlerType: (*RouteGuideServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "GetFeature",
|
||||
Handler: _RouteGuide_GetFeature_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{
|
||||
{
|
||||
StreamName: "ListFeatures",
|
||||
Handler: _RouteGuide_ListFeatures_Handler,
|
||||
ServerStreams: true,
|
||||
},
|
||||
{
|
||||
StreamName: "RecordRoute",
|
||||
Handler: _RouteGuide_RecordRoute_Handler,
|
||||
ClientStreams: true,
|
||||
},
|
||||
{
|
||||
StreamName: "RouteChat",
|
||||
Handler: _RouteGuide_RouteChat_Handler,
|
||||
ServerStreams: true,
|
||||
ClientStreams: true,
|
||||
},
|
||||
},
|
||||
Metadata: "examples/route_guide/routeguide/route_guide.proto",
|
||||
}
|
845
route_guide/server/server.go
Normal file
845
route_guide/server/server.go
Normal file
|
@ -0,0 +1,845 @@
|
|||
/*
|
||||
*
|
||||
* Copyright 2015 gRPC authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
// Package main implements a simple gRPC server that demonstrates how to use gRPC-Go libraries
|
||||
// to perform unary, client streaming, server streaming and full duplex RPCs.
|
||||
//
|
||||
// It implements the route guide service whose definition can be found in routeguide/route_guide.proto.
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"math"
|
||||
"net"
|
||||
"os"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials"
|
||||
"google.golang.org/grpc/examples/data"
|
||||
"google.golang.org/protobuf/proto"
|
||||
|
||||
pb "google.golang.org/grpc/examples/route_guide/routeguide"
|
||||
)
|
||||
|
||||
var (
|
||||
tls = flag.Bool("tls", false, "Connection uses TLS if true, else plain TCP")
|
||||
certFile = flag.String("cert_file", "", "The TLS cert file")
|
||||
keyFile = flag.String("key_file", "", "The TLS key file")
|
||||
jsonDBFile = flag.String("json_db_file", "", "A json file containing a list of features")
|
||||
port = flag.Int("port", 50051, "The server port")
|
||||
)
|
||||
|
||||
type routeGuideServer struct {
|
||||
pb.UnimplementedRouteGuideServer
|
||||
savedFeatures []*pb.Feature // read-only after initialized
|
||||
|
||||
mu sync.Mutex // protects routeNotes
|
||||
routeNotes map[string][]*pb.RouteNote
|
||||
}
|
||||
|
||||
// GetFeature returns the feature at the given point.
|
||||
func (s *routeGuideServer) GetFeature(ctx context.Context, point *pb.Point) (*pb.Feature, error) {
|
||||
for _, feature := range s.savedFeatures {
|
||||
if proto.Equal(feature.Location, point) {
|
||||
return feature, nil
|
||||
}
|
||||
}
|
||||
// No feature was found, return an unnamed feature
|
||||
return &pb.Feature{Location: point}, nil
|
||||
}
|
||||
|
||||
// ListFeatures lists all features contained within the given bounding Rectangle.
|
||||
func (s *routeGuideServer) ListFeatures(rect *pb.Rectangle, stream pb.RouteGuide_ListFeaturesServer) error {
|
||||
for _, feature := range s.savedFeatures {
|
||||
if inRange(feature.Location, rect) {
|
||||
if err := stream.Send(feature); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// RecordRoute records a route composited of a sequence of points.
|
||||
//
|
||||
// It gets a stream of points, and responds with statistics about the "trip":
|
||||
// number of points, number of known features visited, total distance traveled, and
|
||||
// total time spent.
|
||||
func (s *routeGuideServer) RecordRoute(stream pb.RouteGuide_RecordRouteServer) error {
|
||||
var pointCount, featureCount, distance int32
|
||||
var lastPoint *pb.Point
|
||||
startTime := time.Now()
|
||||
for {
|
||||
point, err := stream.Recv()
|
||||
if err == io.EOF {
|
||||
endTime := time.Now()
|
||||
return stream.SendAndClose(&pb.RouteSummary{
|
||||
PointCount: pointCount,
|
||||
FeatureCount: featureCount,
|
||||
Distance: distance,
|
||||
ElapsedTime: int32(endTime.Sub(startTime).Seconds()),
|
||||
})
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pointCount++
|
||||
for _, feature := range s.savedFeatures {
|
||||
if proto.Equal(feature.Location, point) {
|
||||
featureCount++
|
||||
}
|
||||
}
|
||||
if lastPoint != nil {
|
||||
distance += calcDistance(lastPoint, point)
|
||||
}
|
||||
lastPoint = point
|
||||
}
|
||||
}
|
||||
|
||||
// RouteChat receives a stream of message/location pairs, and responds with a stream of all
|
||||
// previous messages at each of those locations.
|
||||
func (s *routeGuideServer) RouteChat(stream pb.RouteGuide_RouteChatServer) error {
|
||||
for {
|
||||
in, err := stream.Recv()
|
||||
if err == io.EOF {
|
||||
return nil
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
key := serialize(in.Location)
|
||||
|
||||
s.mu.Lock()
|
||||
s.routeNotes[key] = append(s.routeNotes[key], in)
|
||||
// Note: this copy prevents blocking other clients while serving this one.
|
||||
// We don't need to do a deep copy, because elements in the slice are
|
||||
// insert-only and never modified.
|
||||
rn := make([]*pb.RouteNote, len(s.routeNotes[key]))
|
||||
copy(rn, s.routeNotes[key])
|
||||
s.mu.Unlock()
|
||||
|
||||
for _, note := range rn {
|
||||
if err := stream.Send(note); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// loadFeatures loads features from a JSON file.
|
||||
func (s *routeGuideServer) loadFeatures(filePath string) {
|
||||
var data []byte
|
||||
if filePath != "" {
|
||||
var err error
|
||||
data, err = os.ReadFile(filePath)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to load default features: %v", err)
|
||||
}
|
||||
} else {
|
||||
data = exampleData
|
||||
}
|
||||
if err := json.Unmarshal(data, &s.savedFeatures); err != nil {
|
||||
log.Fatalf("Failed to load default features: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func toRadians(num float64) float64 {
|
||||
return num * math.Pi / float64(180)
|
||||
}
|
||||
|
||||
// calcDistance calculates the distance between two points using the "haversine" formula.
|
||||
// The formula is based on http://mathforum.org/library/drmath/view/51879.html.
|
||||
func calcDistance(p1 *pb.Point, p2 *pb.Point) int32 {
|
||||
const CordFactor float64 = 1e7
|
||||
const R = float64(6371000) // earth radius in metres
|
||||
lat1 := toRadians(float64(p1.Latitude) / CordFactor)
|
||||
lat2 := toRadians(float64(p2.Latitude) / CordFactor)
|
||||
lng1 := toRadians(float64(p1.Longitude) / CordFactor)
|
||||
lng2 := toRadians(float64(p2.Longitude) / CordFactor)
|
||||
dlat := lat2 - lat1
|
||||
dlng := lng2 - lng1
|
||||
|
||||
a := math.Sin(dlat/2)*math.Sin(dlat/2) +
|
||||
math.Cos(lat1)*math.Cos(lat2)*
|
||||
math.Sin(dlng/2)*math.Sin(dlng/2)
|
||||
c := 2 * math.Atan2(math.Sqrt(a), math.Sqrt(1-a))
|
||||
|
||||
distance := R * c
|
||||
return int32(distance)
|
||||
}
|
||||
|
||||
func inRange(point *pb.Point, rect *pb.Rectangle) bool {
|
||||
left := math.Min(float64(rect.Lo.Longitude), float64(rect.Hi.Longitude))
|
||||
right := math.Max(float64(rect.Lo.Longitude), float64(rect.Hi.Longitude))
|
||||
top := math.Max(float64(rect.Lo.Latitude), float64(rect.Hi.Latitude))
|
||||
bottom := math.Min(float64(rect.Lo.Latitude), float64(rect.Hi.Latitude))
|
||||
|
||||
if float64(point.Longitude) >= left &&
|
||||
float64(point.Longitude) <= right &&
|
||||
float64(point.Latitude) >= bottom &&
|
||||
float64(point.Latitude) <= top {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func serialize(point *pb.Point) string {
|
||||
return fmt.Sprintf("%d %d", point.Latitude, point.Longitude)
|
||||
}
|
||||
|
||||
func newServer() *routeGuideServer {
|
||||
s := &routeGuideServer{routeNotes: make(map[string][]*pb.RouteNote)}
|
||||
s.loadFeatures(*jsonDBFile)
|
||||
return s
|
||||
}
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
lis, err := net.Listen("tcp", fmt.Sprintf("localhost:%d", *port))
|
||||
if err != nil {
|
||||
log.Fatalf("failed to listen: %v", err)
|
||||
}
|
||||
var opts []grpc.ServerOption
|
||||
if *tls {
|
||||
if *certFile == "" {
|
||||
*certFile = data.Path("x509/server_cert.pem")
|
||||
}
|
||||
if *keyFile == "" {
|
||||
*keyFile = data.Path("x509/server_key.pem")
|
||||
}
|
||||
creds, err := credentials.NewServerTLSFromFile(*certFile, *keyFile)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to generate credentials: %v", err)
|
||||
}
|
||||
opts = []grpc.ServerOption{grpc.Creds(creds)}
|
||||
}
|
||||
grpcServer := grpc.NewServer(opts...)
|
||||
pb.RegisterRouteGuideServer(grpcServer, newServer())
|
||||
grpcServer.Serve(lis)
|
||||
}
|
||||
|
||||
// exampleData is a copy of testdata/route_guide_db.json. It's to avoid
|
||||
// specifying file path with `go run`.
|
||||
var exampleData = []byte(`[{
|
||||
"location": {
|
||||
"latitude": 407838351,
|
||||
"longitude": -746143763
|
||||
},
|
||||
"name": "Patriots Path, Mendham, NJ 07945, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 408122808,
|
||||
"longitude": -743999179
|
||||
},
|
||||
"name": "101 New Jersey 10, Whippany, NJ 07981, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 413628156,
|
||||
"longitude": -749015468
|
||||
},
|
||||
"name": "U.S. 6, Shohola, PA 18458, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 419999544,
|
||||
"longitude": -740371136
|
||||
},
|
||||
"name": "5 Conners Road, Kingston, NY 12401, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 414008389,
|
||||
"longitude": -743951297
|
||||
},
|
||||
"name": "Mid Hudson Psychiatric Center, New Hampton, NY 10958, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 419611318,
|
||||
"longitude": -746524769
|
||||
},
|
||||
"name": "287 Flugertown Road, Livingston Manor, NY 12758, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 406109563,
|
||||
"longitude": -742186778
|
||||
},
|
||||
"name": "4001 Tremley Point Road, Linden, NJ 07036, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 416802456,
|
||||
"longitude": -742370183
|
||||
},
|
||||
"name": "352 South Mountain Road, Wallkill, NY 12589, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 412950425,
|
||||
"longitude": -741077389
|
||||
},
|
||||
"name": "Bailey Turn Road, Harriman, NY 10926, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 412144655,
|
||||
"longitude": -743949739
|
||||
},
|
||||
"name": "193-199 Wawayanda Road, Hewitt, NJ 07421, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 415736605,
|
||||
"longitude": -742847522
|
||||
},
|
||||
"name": "406-496 Ward Avenue, Pine Bush, NY 12566, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 413843930,
|
||||
"longitude": -740501726
|
||||
},
|
||||
"name": "162 Merrill Road, Highland Mills, NY 10930, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 410873075,
|
||||
"longitude": -744459023
|
||||
},
|
||||
"name": "Clinton Road, West Milford, NJ 07480, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 412346009,
|
||||
"longitude": -744026814
|
||||
},
|
||||
"name": "16 Old Brook Lane, Warwick, NY 10990, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 402948455,
|
||||
"longitude": -747903913
|
||||
},
|
||||
"name": "3 Drake Lane, Pennington, NJ 08534, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 406337092,
|
||||
"longitude": -740122226
|
||||
},
|
||||
"name": "6324 8th Avenue, Brooklyn, NY 11220, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 406421967,
|
||||
"longitude": -747727624
|
||||
},
|
||||
"name": "1 Merck Access Road, Whitehouse Station, NJ 08889, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 416318082,
|
||||
"longitude": -749677716
|
||||
},
|
||||
"name": "78-98 Schalck Road, Narrowsburg, NY 12764, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 415301720,
|
||||
"longitude": -748416257
|
||||
},
|
||||
"name": "282 Lakeview Drive Road, Highland Lake, NY 12743, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 402647019,
|
||||
"longitude": -747071791
|
||||
},
|
||||
"name": "330 Evelyn Avenue, Hamilton Township, NJ 08619, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 412567807,
|
||||
"longitude": -741058078
|
||||
},
|
||||
"name": "New York State Reference Route 987E, Southfields, NY 10975, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 416855156,
|
||||
"longitude": -744420597
|
||||
},
|
||||
"name": "103-271 Tempaloni Road, Ellenville, NY 12428, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 404663628,
|
||||
"longitude": -744820157
|
||||
},
|
||||
"name": "1300 Airport Road, North Brunswick Township, NJ 08902, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 407113723,
|
||||
"longitude": -749746483
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 402133926,
|
||||
"longitude": -743613249
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 400273442,
|
||||
"longitude": -741220915
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 411236786,
|
||||
"longitude": -744070769
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 411633782,
|
||||
"longitude": -746784970
|
||||
},
|
||||
"name": "211-225 Plains Road, Augusta, NJ 07822, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 415830701,
|
||||
"longitude": -742952812
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 413447164,
|
||||
"longitude": -748712898
|
||||
},
|
||||
"name": "165 Pedersen Ridge Road, Milford, PA 18337, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 405047245,
|
||||
"longitude": -749800722
|
||||
},
|
||||
"name": "100-122 Locktown Road, Frenchtown, NJ 08825, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 418858923,
|
||||
"longitude": -746156790
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 417951888,
|
||||
"longitude": -748484944
|
||||
},
|
||||
"name": "650-652 Willi Hill Road, Swan Lake, NY 12783, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 407033786,
|
||||
"longitude": -743977337
|
||||
},
|
||||
"name": "26 East 3rd Street, New Providence, NJ 07974, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 417548014,
|
||||
"longitude": -740075041
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 410395868,
|
||||
"longitude": -744972325
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 404615353,
|
||||
"longitude": -745129803
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 406589790,
|
||||
"longitude": -743560121
|
||||
},
|
||||
"name": "611 Lawrence Avenue, Westfield, NJ 07090, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 414653148,
|
||||
"longitude": -740477477
|
||||
},
|
||||
"name": "18 Lannis Avenue, New Windsor, NY 12553, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 405957808,
|
||||
"longitude": -743255336
|
||||
},
|
||||
"name": "82-104 Amherst Avenue, Colonia, NJ 07067, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 411733589,
|
||||
"longitude": -741648093
|
||||
},
|
||||
"name": "170 Seven Lakes Drive, Sloatsburg, NY 10974, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 412676291,
|
||||
"longitude": -742606606
|
||||
},
|
||||
"name": "1270 Lakes Road, Monroe, NY 10950, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 409224445,
|
||||
"longitude": -748286738
|
||||
},
|
||||
"name": "509-535 Alphano Road, Great Meadows, NJ 07838, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 406523420,
|
||||
"longitude": -742135517
|
||||
},
|
||||
"name": "652 Garden Street, Elizabeth, NJ 07202, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 401827388,
|
||||
"longitude": -740294537
|
||||
},
|
||||
"name": "349 Sea Spray Court, Neptune City, NJ 07753, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 410564152,
|
||||
"longitude": -743685054
|
||||
},
|
||||
"name": "13-17 Stanley Street, West Milford, NJ 07480, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 408472324,
|
||||
"longitude": -740726046
|
||||
},
|
||||
"name": "47 Industrial Avenue, Teterboro, NJ 07608, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 412452168,
|
||||
"longitude": -740214052
|
||||
},
|
||||
"name": "5 White Oak Lane, Stony Point, NY 10980, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 409146138,
|
||||
"longitude": -746188906
|
||||
},
|
||||
"name": "Berkshire Valley Management Area Trail, Jefferson, NJ, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 404701380,
|
||||
"longitude": -744781745
|
||||
},
|
||||
"name": "1007 Jersey Avenue, New Brunswick, NJ 08901, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 409642566,
|
||||
"longitude": -746017679
|
||||
},
|
||||
"name": "6 East Emerald Isle Drive, Lake Hopatcong, NJ 07849, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 408031728,
|
||||
"longitude": -748645385
|
||||
},
|
||||
"name": "1358-1474 New Jersey 57, Port Murray, NJ 07865, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 413700272,
|
||||
"longitude": -742135189
|
||||
},
|
||||
"name": "367 Prospect Road, Chester, NY 10918, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 404310607,
|
||||
"longitude": -740282632
|
||||
},
|
||||
"name": "10 Simon Lake Drive, Atlantic Highlands, NJ 07716, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 409319800,
|
||||
"longitude": -746201391
|
||||
},
|
||||
"name": "11 Ward Street, Mount Arlington, NJ 07856, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 406685311,
|
||||
"longitude": -742108603
|
||||
},
|
||||
"name": "300-398 Jefferson Avenue, Elizabeth, NJ 07201, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 419018117,
|
||||
"longitude": -749142781
|
||||
},
|
||||
"name": "43 Dreher Road, Roscoe, NY 12776, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 412856162,
|
||||
"longitude": -745148837
|
||||
},
|
||||
"name": "Swan Street, Pine Island, NY 10969, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 416560744,
|
||||
"longitude": -746721964
|
||||
},
|
||||
"name": "66 Pleasantview Avenue, Monticello, NY 12701, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 405314270,
|
||||
"longitude": -749836354
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 414219548,
|
||||
"longitude": -743327440
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 415534177,
|
||||
"longitude": -742900616
|
||||
},
|
||||
"name": "565 Winding Hills Road, Montgomery, NY 12549, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 406898530,
|
||||
"longitude": -749127080
|
||||
},
|
||||
"name": "231 Rocky Run Road, Glen Gardner, NJ 08826, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 407586880,
|
||||
"longitude": -741670168
|
||||
},
|
||||
"name": "100 Mount Pleasant Avenue, Newark, NJ 07104, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 400106455,
|
||||
"longitude": -742870190
|
||||
},
|
||||
"name": "517-521 Huntington Drive, Manchester Township, NJ 08759, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 400066188,
|
||||
"longitude": -746793294
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 418803880,
|
||||
"longitude": -744102673
|
||||
},
|
||||
"name": "40 Mountain Road, Napanoch, NY 12458, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 414204288,
|
||||
"longitude": -747895140
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 414777405,
|
||||
"longitude": -740615601
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 415464475,
|
||||
"longitude": -747175374
|
||||
},
|
||||
"name": "48 North Road, Forestburgh, NY 12777, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 404062378,
|
||||
"longitude": -746376177
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 405688272,
|
||||
"longitude": -749285130
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 400342070,
|
||||
"longitude": -748788996
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 401809022,
|
||||
"longitude": -744157964
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 404226644,
|
||||
"longitude": -740517141
|
||||
},
|
||||
"name": "9 Thompson Avenue, Leonardo, NJ 07737, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 410322033,
|
||||
"longitude": -747871659
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 407100674,
|
||||
"longitude": -747742727
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 418811433,
|
||||
"longitude": -741718005
|
||||
},
|
||||
"name": "213 Bush Road, Stone Ridge, NY 12484, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 415034302,
|
||||
"longitude": -743850945
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 411349992,
|
||||
"longitude": -743694161
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 404839914,
|
||||
"longitude": -744759616
|
||||
},
|
||||
"name": "1-17 Bergen Court, New Brunswick, NJ 08901, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 414638017,
|
||||
"longitude": -745957854
|
||||
},
|
||||
"name": "35 Oakland Valley Road, Cuddebackville, NY 12729, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 412127800,
|
||||
"longitude": -740173578
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 401263460,
|
||||
"longitude": -747964303
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 412843391,
|
||||
"longitude": -749086026
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 418512773,
|
||||
"longitude": -743067823
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 404318328,
|
||||
"longitude": -740835638
|
||||
},
|
||||
"name": "42-102 Main Street, Belford, NJ 07718, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 419020746,
|
||||
"longitude": -741172328
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 404080723,
|
||||
"longitude": -746119569
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 401012643,
|
||||
"longitude": -744035134
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 404306372,
|
||||
"longitude": -741079661
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 403966326,
|
||||
"longitude": -748519297
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 405002031,
|
||||
"longitude": -748407866
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 409532885,
|
||||
"longitude": -742200683
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 416851321,
|
||||
"longitude": -742674555
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 406411633,
|
||||
"longitude": -741722051
|
||||
},
|
||||
"name": "3387 Richmond Terrace, Staten Island, NY 10303, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 413069058,
|
||||
"longitude": -744597778
|
||||
},
|
||||
"name": "261 Van Sickle Road, Goshen, NY 10924, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 418465462,
|
||||
"longitude": -746859398
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 411733222,
|
||||
"longitude": -744228360
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 410248224,
|
||||
"longitude": -747127767
|
||||
},
|
||||
"name": "3 Hasta Way, Newton, NJ 07860, USA"
|
||||
}]`)
|
601
route_guide/testdata/route_guide_db.json
vendored
Normal file
601
route_guide/testdata/route_guide_db.json
vendored
Normal file
|
@ -0,0 +1,601 @@
|
|||
[{
|
||||
"location": {
|
||||
"latitude": 407838351,
|
||||
"longitude": -746143763
|
||||
},
|
||||
"name": "Patriots Path, Mendham, NJ 07945, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 408122808,
|
||||
"longitude": -743999179
|
||||
},
|
||||
"name": "101 New Jersey 10, Whippany, NJ 07981, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 413628156,
|
||||
"longitude": -749015468
|
||||
},
|
||||
"name": "U.S. 6, Shohola, PA 18458, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 419999544,
|
||||
"longitude": -740371136
|
||||
},
|
||||
"name": "5 Conners Road, Kingston, NY 12401, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 414008389,
|
||||
"longitude": -743951297
|
||||
},
|
||||
"name": "Mid Hudson Psychiatric Center, New Hampton, NY 10958, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 419611318,
|
||||
"longitude": -746524769
|
||||
},
|
||||
"name": "287 Flugertown Road, Livingston Manor, NY 12758, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 406109563,
|
||||
"longitude": -742186778
|
||||
},
|
||||
"name": "4001 Tremley Point Road, Linden, NJ 07036, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 416802456,
|
||||
"longitude": -742370183
|
||||
},
|
||||
"name": "352 South Mountain Road, Wallkill, NY 12589, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 412950425,
|
||||
"longitude": -741077389
|
||||
},
|
||||
"name": "Bailey Turn Road, Harriman, NY 10926, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 412144655,
|
||||
"longitude": -743949739
|
||||
},
|
||||
"name": "193-199 Wawayanda Road, Hewitt, NJ 07421, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 415736605,
|
||||
"longitude": -742847522
|
||||
},
|
||||
"name": "406-496 Ward Avenue, Pine Bush, NY 12566, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 413843930,
|
||||
"longitude": -740501726
|
||||
},
|
||||
"name": "162 Merrill Road, Highland Mills, NY 10930, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 410873075,
|
||||
"longitude": -744459023
|
||||
},
|
||||
"name": "Clinton Road, West Milford, NJ 07480, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 412346009,
|
||||
"longitude": -744026814
|
||||
},
|
||||
"name": "16 Old Brook Lane, Warwick, NY 10990, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 402948455,
|
||||
"longitude": -747903913
|
||||
},
|
||||
"name": "3 Drake Lane, Pennington, NJ 08534, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 406337092,
|
||||
"longitude": -740122226
|
||||
},
|
||||
"name": "6324 8th Avenue, Brooklyn, NY 11220, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 406421967,
|
||||
"longitude": -747727624
|
||||
},
|
||||
"name": "1 Merck Access Road, Whitehouse Station, NJ 08889, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 416318082,
|
||||
"longitude": -749677716
|
||||
},
|
||||
"name": "78-98 Schalck Road, Narrowsburg, NY 12764, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 415301720,
|
||||
"longitude": -748416257
|
||||
},
|
||||
"name": "282 Lakeview Drive Road, Highland Lake, NY 12743, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 402647019,
|
||||
"longitude": -747071791
|
||||
},
|
||||
"name": "330 Evelyn Avenue, Hamilton Township, NJ 08619, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 412567807,
|
||||
"longitude": -741058078
|
||||
},
|
||||
"name": "New York State Reference Route 987E, Southfields, NY 10975, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 416855156,
|
||||
"longitude": -744420597
|
||||
},
|
||||
"name": "103-271 Tempaloni Road, Ellenville, NY 12428, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 404663628,
|
||||
"longitude": -744820157
|
||||
},
|
||||
"name": "1300 Airport Road, North Brunswick Township, NJ 08902, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 407113723,
|
||||
"longitude": -749746483
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 402133926,
|
||||
"longitude": -743613249
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 400273442,
|
||||
"longitude": -741220915
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 411236786,
|
||||
"longitude": -744070769
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 411633782,
|
||||
"longitude": -746784970
|
||||
},
|
||||
"name": "211-225 Plains Road, Augusta, NJ 07822, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 415830701,
|
||||
"longitude": -742952812
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 413447164,
|
||||
"longitude": -748712898
|
||||
},
|
||||
"name": "165 Pedersen Ridge Road, Milford, PA 18337, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 405047245,
|
||||
"longitude": -749800722
|
||||
},
|
||||
"name": "100-122 Locktown Road, Frenchtown, NJ 08825, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 418858923,
|
||||
"longitude": -746156790
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 417951888,
|
||||
"longitude": -748484944
|
||||
},
|
||||
"name": "650-652 Willi Hill Road, Swan Lake, NY 12783, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 407033786,
|
||||
"longitude": -743977337
|
||||
},
|
||||
"name": "26 East 3rd Street, New Providence, NJ 07974, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 417548014,
|
||||
"longitude": -740075041
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 410395868,
|
||||
"longitude": -744972325
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 404615353,
|
||||
"longitude": -745129803
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 406589790,
|
||||
"longitude": -743560121
|
||||
},
|
||||
"name": "611 Lawrence Avenue, Westfield, NJ 07090, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 414653148,
|
||||
"longitude": -740477477
|
||||
},
|
||||
"name": "18 Lannis Avenue, New Windsor, NY 12553, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 405957808,
|
||||
"longitude": -743255336
|
||||
},
|
||||
"name": "82-104 Amherst Avenue, Colonia, NJ 07067, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 411733589,
|
||||
"longitude": -741648093
|
||||
},
|
||||
"name": "170 Seven Lakes Drive, Sloatsburg, NY 10974, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 412676291,
|
||||
"longitude": -742606606
|
||||
},
|
||||
"name": "1270 Lakes Road, Monroe, NY 10950, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 409224445,
|
||||
"longitude": -748286738
|
||||
},
|
||||
"name": "509-535 Alphano Road, Great Meadows, NJ 07838, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 406523420,
|
||||
"longitude": -742135517
|
||||
},
|
||||
"name": "652 Garden Street, Elizabeth, NJ 07202, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 401827388,
|
||||
"longitude": -740294537
|
||||
},
|
||||
"name": "349 Sea Spray Court, Neptune City, NJ 07753, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 410564152,
|
||||
"longitude": -743685054
|
||||
},
|
||||
"name": "13-17 Stanley Street, West Milford, NJ 07480, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 408472324,
|
||||
"longitude": -740726046
|
||||
},
|
||||
"name": "47 Industrial Avenue, Teterboro, NJ 07608, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 412452168,
|
||||
"longitude": -740214052
|
||||
},
|
||||
"name": "5 White Oak Lane, Stony Point, NY 10980, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 409146138,
|
||||
"longitude": -746188906
|
||||
},
|
||||
"name": "Berkshire Valley Management Area Trail, Jefferson, NJ, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 404701380,
|
||||
"longitude": -744781745
|
||||
},
|
||||
"name": "1007 Jersey Avenue, New Brunswick, NJ 08901, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 409642566,
|
||||
"longitude": -746017679
|
||||
},
|
||||
"name": "6 East Emerald Isle Drive, Lake Hopatcong, NJ 07849, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 408031728,
|
||||
"longitude": -748645385
|
||||
},
|
||||
"name": "1358-1474 New Jersey 57, Port Murray, NJ 07865, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 413700272,
|
||||
"longitude": -742135189
|
||||
},
|
||||
"name": "367 Prospect Road, Chester, NY 10918, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 404310607,
|
||||
"longitude": -740282632
|
||||
},
|
||||
"name": "10 Simon Lake Drive, Atlantic Highlands, NJ 07716, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 409319800,
|
||||
"longitude": -746201391
|
||||
},
|
||||
"name": "11 Ward Street, Mount Arlington, NJ 07856, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 406685311,
|
||||
"longitude": -742108603
|
||||
},
|
||||
"name": "300-398 Jefferson Avenue, Elizabeth, NJ 07201, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 419018117,
|
||||
"longitude": -749142781
|
||||
},
|
||||
"name": "43 Dreher Road, Roscoe, NY 12776, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 412856162,
|
||||
"longitude": -745148837
|
||||
},
|
||||
"name": "Swan Street, Pine Island, NY 10969, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 416560744,
|
||||
"longitude": -746721964
|
||||
},
|
||||
"name": "66 Pleasantview Avenue, Monticello, NY 12701, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 405314270,
|
||||
"longitude": -749836354
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 414219548,
|
||||
"longitude": -743327440
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 415534177,
|
||||
"longitude": -742900616
|
||||
},
|
||||
"name": "565 Winding Hills Road, Montgomery, NY 12549, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 406898530,
|
||||
"longitude": -749127080
|
||||
},
|
||||
"name": "231 Rocky Run Road, Glen Gardner, NJ 08826, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 407586880,
|
||||
"longitude": -741670168
|
||||
},
|
||||
"name": "100 Mount Pleasant Avenue, Newark, NJ 07104, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 400106455,
|
||||
"longitude": -742870190
|
||||
},
|
||||
"name": "517-521 Huntington Drive, Manchester Township, NJ 08759, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 400066188,
|
||||
"longitude": -746793294
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 418803880,
|
||||
"longitude": -744102673
|
||||
},
|
||||
"name": "40 Mountain Road, Napanoch, NY 12458, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 414204288,
|
||||
"longitude": -747895140
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 414777405,
|
||||
"longitude": -740615601
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 415464475,
|
||||
"longitude": -747175374
|
||||
},
|
||||
"name": "48 North Road, Forestburgh, NY 12777, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 404062378,
|
||||
"longitude": -746376177
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 405688272,
|
||||
"longitude": -749285130
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 400342070,
|
||||
"longitude": -748788996
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 401809022,
|
||||
"longitude": -744157964
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 404226644,
|
||||
"longitude": -740517141
|
||||
},
|
||||
"name": "9 Thompson Avenue, Leonardo, NJ 07737, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 410322033,
|
||||
"longitude": -747871659
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 407100674,
|
||||
"longitude": -747742727
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 418811433,
|
||||
"longitude": -741718005
|
||||
},
|
||||
"name": "213 Bush Road, Stone Ridge, NY 12484, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 415034302,
|
||||
"longitude": -743850945
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 411349992,
|
||||
"longitude": -743694161
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 404839914,
|
||||
"longitude": -744759616
|
||||
},
|
||||
"name": "1-17 Bergen Court, New Brunswick, NJ 08901, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 414638017,
|
||||
"longitude": -745957854
|
||||
},
|
||||
"name": "35 Oakland Valley Road, Cuddebackville, NY 12729, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 412127800,
|
||||
"longitude": -740173578
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 401263460,
|
||||
"longitude": -747964303
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 412843391,
|
||||
"longitude": -749086026
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 418512773,
|
||||
"longitude": -743067823
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 404318328,
|
||||
"longitude": -740835638
|
||||
},
|
||||
"name": "42-102 Main Street, Belford, NJ 07718, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 419020746,
|
||||
"longitude": -741172328
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 404080723,
|
||||
"longitude": -746119569
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 401012643,
|
||||
"longitude": -744035134
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 404306372,
|
||||
"longitude": -741079661
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 403966326,
|
||||
"longitude": -748519297
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 405002031,
|
||||
"longitude": -748407866
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 409532885,
|
||||
"longitude": -742200683
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 416851321,
|
||||
"longitude": -742674555
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 406411633,
|
||||
"longitude": -741722051
|
||||
},
|
||||
"name": "3387 Richmond Terrace, Staten Island, NY 10303, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 413069058,
|
||||
"longitude": -744597778
|
||||
},
|
||||
"name": "261 Van Sickle Road, Goshen, NY 10924, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 418465462,
|
||||
"longitude": -746859398
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 411733222,
|
||||
"longitude": -744228360
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 410248224,
|
||||
"longitude": -747127767
|
||||
},
|
||||
"name": "3 Hasta Way, Newton, NJ 07860, USA"
|
||||
}]
|
52
stepik/intro.go
Normal file
52
stepik/intro.go
Normal file
|
@ -0,0 +1,52 @@
|
|||
package stepik
|
||||
|
||||
import "fmt"
|
||||
|
||||
func ScanManipulations() int {
|
||||
var a int
|
||||
fmt.Scan(&a)
|
||||
a = a*2 + 100
|
||||
fmt.Print(a)
|
||||
return a*2 + 100
|
||||
}
|
||||
|
||||
func PetrErrorCode() {
|
||||
var a int
|
||||
var b int
|
||||
fmt.Scan(&a)
|
||||
fmt.Scan(&b)
|
||||
|
||||
a = a * a
|
||||
b = b * 2
|
||||
c := a + b
|
||||
fmt.Println(c)
|
||||
}
|
||||
|
||||
func SquareTask() {
|
||||
var a int
|
||||
fmt.Scan(&a)
|
||||
fmt.Print(a * a)
|
||||
}
|
||||
|
||||
func LastNumberTask() {
|
||||
var a int
|
||||
fmt.Scan(&a)
|
||||
fmt.Print(a % 10)
|
||||
}
|
||||
|
||||
func PreLastNumberTask() {
|
||||
// Дано неотрицательное целое число. Найдите число десятков (то есть вторую цифру справа).
|
||||
var a int
|
||||
fmt.Scan(&a)
|
||||
fmt.Print(a % 100 / 10)
|
||||
}
|
||||
|
||||
func ClockTask() {
|
||||
// Часовая стрелка повернулась с начала суток на d градусов. Определите, сколько сейчас целых часов h и целых минут m.
|
||||
var a int
|
||||
var hours_degrees int = 360 / 12
|
||||
fmt.Scan(&a)
|
||||
fmt.Println(a / hours_degrees)
|
||||
fmt.Println(a % 30 * 2)
|
||||
fmt.Printf("It is %d hours %d minutes.", a/hours_degrees, a%30*2)
|
||||
}
|
Loading…
Reference in a new issue