Skip to content

Instantly share code, notes, and snippets.

@mortymacs
Last active March 30, 2023 15:09
Show Gist options
  • Save mortymacs/dddca4983ae5b227721a2cadbda026bf to your computer and use it in GitHub Desktop.
Save mortymacs/dddca4983ae5b227721a2cadbda026bf to your computer and use it in GitHub Desktop.
Implement multi-driver search provider in Go
package main
import (
"encoding/json"
"fmt"
)
// Driver
type Google struct {
APIKey string
}
type GoogleSearch struct {
Keyword string
Lang string
}
type GoogleGet struct {
ID string
}
type GoogleResult struct {
ID string
Title string
}
type GoogleItem struct {
ID string
Title string
Description string
}
func (g Google) Search(googleSearch GoogleSearch) GoogleResult {
fmt.Println("Google search:", googleSearch)
//return GoogleResult{
return GoogleResult{
ID: "123",
Title: "something",
}
}
func (g Google) Get(googleGet GoogleGet) GoogleItem {
fmt.Println("Google get:", googleGet.ID)
return GoogleItem{
ID: "123",
Title: "something",
Description: "something details",
}
}
type You struct {
APIKey string
Username string
}
type YouSearch struct {
Query []string
Engine string
}
type YouGet struct {
UID string
Link string
}
type YouResult struct {
UID string
Breif string
Link string
}
type YouItem struct {
UID string
Info string
}
func (y You) Search(youSearch YouSearch) YouResult {
fmt.Println("You search:", youSearch)
return YouResult{
UID: "uid",
Breif: "some description",
Link: "link",
}
}
func (y You) Get(youGet YouGet) YouItem {
fmt.Println("You get:", youGet.UID, youGet.Link)
return YouItem{
UID: youGet.UID,
Info: "some info",
}
}
// Client
type GoogleOption func(g *GoogleClient)
type GoogleClient struct {
Keyword string
Lang string
Google Google
}
func NewGoogleClient(apiKey string, options ...GoogleOption) GoogleClient {
g := GoogleClient{
Google: Google{
APIKey: apiKey,
},
// Put default values if needed.
}
for _, opt := range options {
opt(&g)
}
return g
}
func WithKeyword(keyword string) GoogleOption {
return func(g *GoogleClient) {
g.Keyword = keyword
}
}
func WithLang(lang string) GoogleOption {
return func(g *GoogleClient) {
g.Lang = lang
}
}
type YouOption func(y *YouClient)
type YouClient struct {
Query []string
Engine string
You You
}
func NewYouClient(apiKey, username string, options ...YouOption) YouClient {
y := YouClient{
You: You{
APIKey: apiKey,
Username: username,
},
// Put default values if needed.
}
for _, opt := range options {
opt(&y)
}
return y
}
func WithQuery(query []string) YouOption {
return func(y *YouClient) {
y.Query = query
}
}
func WithEngine(engine string) YouOption {
return func(y *YouClient) {
y.Engine = engine
}
}
// Interface
type Searcher interface {
Search() Payloader
//Get() Payloader
}
type Payloader interface {
Cleanup()
Encryption()
Dump() any
}
type CustomizedGoogleResult struct {
GoogleResult
}
func (g CustomizedGoogleResult) Cleanup() {
fmt.Println("Cleanup")
}
func (g CustomizedGoogleResult) Encryption() {
fmt.Println("Encryption")
}
func (g CustomizedGoogleResult) Dump() any {
return g.GoogleResult
}
func (g GoogleClient) Search() Payloader {
cr := CustomizedGoogleResult{
g.Google.Search(GoogleSearch{
Keyword: g.Keyword,
Lang: g.Lang,
}),
}
cr.Cleanup()
cr.Encryption()
return cr
}
type CustomizedYouResult struct {
YouResult
}
func (y CustomizedYouResult) Cleanup() {
fmt.Println("Cleanup")
}
func (y CustomizedYouResult) Encryption() {
fmt.Println("Encryption")
}
func (y CustomizedYouResult) Dump() any {
return y.YouResult
}
func (y YouClient) Search() Payloader {
yr := CustomizedYouResult{
y.You.Search(YouSearch{
Query: y.Query,
Engine: y.Engine,
}),
}
yr.Cleanup()
yr.Encryption()
return yr
}
// Wrapper
func Provider(provider string) Searcher {
if provider == "google" {
return NewGoogleClient("123")
}
return NewYouClient("123", "admin")
}
// Test
func main() {
g := NewGoogleClient("123", WithKeyword("Mort"), WithLang("EN"))
gr := g.Search()
e, _ := json.Marshal(gr.Dump())
fmt.Println(string(e))
y := NewYouClient("123", "admin", WithEngine("chatgpt"))
yr := y.Search()
e, _ = json.Marshal(yr.Dump())
fmt.Println(string(e))
p := Provider("google")
pr := p.Search()
e, _ = json.Marshal(pr.Dump())
fmt.Println(string(e))
}
package main
import (
"encoding/json"
"fmt"
)
// Driver
type Google struct {
APIKey string
}
type GoogleSearch struct {
Keyword string
Lang string
}
type GoogleGet struct {
ID string
}
type GoogleResult struct {
ID string
Title string
}
type GoogleItem struct {
ID string
Title string
Description string
}
func (g Google) Search(googleSearch GoogleSearch) GoogleResult {
fmt.Println("Google search:", googleSearch)
//return GoogleResult{
return GoogleResult{
ID: "123",
Title: "something",
}
}
func (g Google) Get(googleGet GoogleGet) GoogleItem {
fmt.Println("Google get:", googleGet.ID)
return GoogleItem{
ID: "123",
Title: "something",
Description: "something details",
}
}
type You struct {
APIKey string
Username string
}
type YouSearch struct {
Query []string
Engine string
}
type YouGet struct {
UID string
Link string
}
type YouResult struct {
UID string
Breif string
Link string
}
type YouItem struct {
UID string
Info string
}
func (y You) Search(youSearch YouSearch) YouResult {
fmt.Println("You search:", youSearch)
return YouResult{
UID: "uid",
Breif: "some description",
Link: "link",
}
}
func (y You) Get(youGet YouGet) YouItem {
fmt.Println("You get:", youGet.UID, youGet.Link)
return YouItem{
UID: youGet.UID,
Info: "some info",
}
}
// Client
type GoogleClient struct {
Keyword string
Lang string
Google Google
}
func NewGoogleClient(apiKey string) GoogleClient {
g := GoogleClient{
Google: Google{
APIKey: apiKey,
},
// Put default values if needed.
}
return g
}
type YouClient struct {
Query []string
Engine string
You You
}
func NewYouClient(apiKey, username string) YouClient {
y := YouClient{
You: You{
APIKey: apiKey,
Username: username,
},
// Put default values if needed.
}
return y
}
// Interface
type Searcher interface {
Search(...Option) Payloader
//Get() Payloader
}
type Payloader interface {
Cleanup()
Encryption()
Dump() any
}
type CustomizedGoogleResult struct {
GoogleResult
}
func (g CustomizedGoogleResult) Cleanup() {
fmt.Println("Cleanup")
}
func (g CustomizedGoogleResult) Encryption() {
fmt.Println("Encryption")
}
func (g CustomizedGoogleResult) Dump() any {
return g.GoogleResult
}
func WithKeyword(keyword string) Option {
return func(g any) {
a := g.(*GoogleSearch)
a.Keyword = keyword
}
}
func WithLang(lang string) Option {
return func(g any) {
a := g.(*GoogleSearch)
a.Lang = lang
}
}
func (g GoogleClient) Search(options ...Option) Payloader {
gs := GoogleSearch{}
for _, opt := range options {
opt(&gs)
}
cr := CustomizedGoogleResult{
g.Google.Search(gs),
}
cr.Cleanup()
cr.Encryption()
return cr
}
type CustomizedYouResult struct {
YouResult
}
func (y CustomizedYouResult) Cleanup() {
fmt.Println("Cleanup")
}
func (y CustomizedYouResult) Encryption() {
fmt.Println("Encryption")
}
func (y CustomizedYouResult) Dump() any {
return y.YouResult
}
type Option func(g any)
func WithQuery(query []string) Option {
return func(y any) {
a, _ := y.(*YouSearch)
a.Query = query
}
}
func WithEngine(engine string) Option {
return func(y any) {
a, _ := y.(*YouSearch)
a.Engine = engine
}
}
func (y YouClient) Search(options ...Option) Payloader {
cy := YouSearch{}
for _, opt := range options {
opt(&y)
}
yr := CustomizedYouResult{
y.You.Search(cy),
}
yr.Cleanup()
yr.Encryption()
return yr
}
// Wrapper
func Provider(provider string) Searcher {
if provider == "google" {
return NewGoogleClient("123")
}
return NewYouClient("123", "admin")
}
// Test
func main() {
g := NewGoogleClient("123")
gr := g.Search()
e, _ := json.Marshal(gr.Dump())
fmt.Println(string(e))
y := NewYouClient("123", "admin")
yr := y.Search()
e, _ = json.Marshal(yr.Dump())
fmt.Println(string(e))
p := Provider("google")
pr := p.Search(WithKeyword("TestTest"))
e, _ = json.Marshal(pr.Dump())
fmt.Println(string(e))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment