Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

persist and restore options #52

Closed
Tracked by #8
plastikfan opened this issue Nov 9, 2022 · 3 comments
Closed
Tracked by #8

persist and restore options #52

plastikfan opened this issue Nov 9, 2022 · 3 comments
Assignees
Labels
feature New feature or request

Comments

@plastikfan
Copy link
Contributor

plastikfan commented Nov 9, 2022

function callbacks on option, will not be persistable, so need to all the client to reset them

@plastikfan plastikfan mentioned this issue Nov 9, 2022
13 tasks
@plastikfan plastikfan added the feature New feature or request label Nov 9, 2022
@plastikfan plastikfan self-assigned this Nov 9, 2022
@plastikfan
Copy link
Contributor Author

plastikfan commented Nov 9, 2022

Dicovered a slight problem with using gob. If a struct has no fields, it can't be serialised, "unexpected EOF" occurs. This also includes situations where a struct only contains non serialisable types, eg func variables as is the case with the Hooks and Notify sections of options. This can be averted by placing a dummy member variable into its definition, but this is a horrible work-around.

Should now explore json serialisation as an alternative to using gob.

@plastikfan
Copy link
Contributor Author

some gob code:

type SerialOptions struct {
	Subscription nav.TraverseSubscription
	DoExtend     bool
	WithMetrics  bool
	Callback     nav.TraverseCallback
	Notify       nav.Notifications
	// Hooks      nav.TraverseHooks
	Behaviours nav.NavigationBehaviours
	Listen     nav.ListenOptions
	Filters    nav.NavigationFilters
}

type Student struct {
	Name string
	Age  int32
}

type FunctionalStudent struct {
	Name string
	Age  int32
	Fn   func(name string, age int32) string
}

type Address struct {
	No     int
	Street string
	Town   string
	County string
	Zip    string
}

type StudentWithAddress struct {
	Name string
	Age  int32
	Home Address
}

func writeGob(filePath string, object interface{}) error {
	file, err := os.Create(filePath)
	if err == nil {
		encoder := gob.NewEncoder(file)
		if e := encoder.Encode(object); e != nil {
			GinkgoWriter.Printf("===> writeGob: err: '~%v'\n", e)
		}
	}
	defer file.Close()
	return err
}

func readGob(filePath string, object interface{}) error {
	file, err := os.Open(filePath)
	if err == nil {
		decoder := gob.NewDecoder(file)
		err = decoder.Decode(object)
	}
	defer file.Close()
	return err
}

func writeBytes(bytes []byte, path string) {
	if file, err := os.Create(path); err == nil {
		defer file.Close()

		if n, e := file.Write(bytes); e == nil {
			GinkgoWriter.Printf("===>  ✨✨✨ writeBytes succeeded: no of bytes: '%v'", n)
		}
	} else {
		GinkgoWriter.Printf("===> 🔥🔥🔥 writeBytes failed: '%v'", err)
	}
}

		Context("save", func() {
			It("🧪 should: write", func() {
				student := Student{"plastikfan", 666}
				if err := writeGob(studentPath, student); err != nil {
					fmt.Println(err)
				}
			})

			It("🧪 should: write(functional)", func() {
				student := FunctionalStudent{
					Name: "scooby doo", Age: 69,
					Fn: func(name string, age int32) string {
						return fmt.Sprintf("NAME: '%v', AGE: '%v'", name, age)
					},
				}
				if err := writeGob(fnStudentPath, student); err != nil {
					fmt.Println(err)
				}
			})

			It("🧪 should: write(with address)", func() {
				student := StudentWithAddress{
					Name: "plastikfan", Age: 666,
					Home: Address{
						No:     42,
						Street: "Rodeo Drive",
						Town:   "Smallstone",
						County: "Silly-shire",
						Zip:    "90201",
					},
				}
				if err := writeGob(studentAddressPath, student); err != nil {
					fmt.Println(err)
				}
			})
		})

		Context("load", func() {
			It("🧪 should: read", func() {
				var student = new(Student)
				if err := readGob(studentPath, student); err != nil {
					fmt.Println(err)
				} else {
					GinkgoWriter.Printf("student: '%+v'\n", student)
				}
			})

			It("🧪 should: read(functional)", func() {
				var student = new(FunctionalStudent)
				if err := readGob(fnStudentPath, student); err != nil {
					fmt.Println(err)
				} else {
					GinkgoWriter.Printf("fn-student: '%+v'\n", student)
				}
			})

			It("🧪 should: read(with-address)", func() {
				var student = new(StudentWithAddress)
				if err := readGob(studentAddressPath, student); err != nil {
					fmt.Println(err)
				} else {
					GinkgoWriter.Printf("student-with-address: '%+v'\n", student)
				}
			})
		})

		Context("options", func() {
			Context("save", func() {
				It("🧪 should: write 🧡🧡", func() {
					if err := writeGob(optionsPath, *o); err != nil {
						fmt.Println(err)
					}
				})
			})

			Context("load", func() {
				It("🧪 should: read 🧡🧡", func() {
					options := new(nav.TraverseOptions)
					if err := readGob(optionsPath, options); err != nil {
						fmt.Println(err)
					} else {
						GinkgoWriter.Printf("options: '%+v'\n", options)
					}
				})
			})
		})

		Context("serial-options", func() {
			Context("save", func() {
				It("🧪 should: write 💛💛", func() {
					if err := writeGob(serialPath, *so); err != nil {
						fmt.Println(err)
					} else {
						GinkgoWriter.Printf("💛💛 serial options written ok")
					}
				})
			})

			Context("load", func() {
				It("🧪 should: read 💛💛", func() {
					options := new(SerialOptions)
					if err := readGob(serialPath, options); err != nil {
						fmt.Println(err)
					} else {
						GinkgoWriter.Printf("💛💛 serial-options read ok: '%+v'\n", options)
					}
				})
			})
		})

plastikfan added a commit that referenced this issue Nov 11, 2022
feat(nav): partially persist options as json (#52)

feat(nav): implement json option marshal (#52)
@plastikfan
Copy link
Contributor Author

The filters need to be refactored so that in the config there are represented in serialisable form. This will be implmeneted by issue #53.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant