From 3eabe484df18a7e8c0a151217c69450417792dac Mon Sep 17 00:00:00 2001 From: xoc Date: Sat, 25 Jun 2022 16:20:35 +0200 Subject: [PATCH 1/3] added int and []byte type --- search.go | 23 ++++++++++++++++++++--- search_test.go | 18 ++++++++++++++++++ v3/search.go | 23 ++++++++++++++++++++--- v3/search_test.go | 18 ++++++++++++++++++ 4 files changed, 76 insertions(+), 6 deletions(-) diff --git a/search.go b/search.go index 5f3d47c5..fc94077b 100644 --- a/search.go +++ b/search.go @@ -5,6 +5,7 @@ import ( "fmt" "reflect" "sort" + "strconv" "strings" ber "github.com/go-asn1-ber/asn1-ber" @@ -184,8 +185,8 @@ func readTag(f reflect.StructField) (string, bool) { // Unmarshal parses the Entry in the value pointed to by i // // Currently, this methods only supports struct fields of type -// string or []string. Other field types will not be regarded. -// If the field type is a string but multiple attribute values +// string, []string, int or []byte. Other field types will not be regarded. +// If the field type is a string or int but multiple attribute values // are returned, the first value will be used to fill the field. // // Example: @@ -203,6 +204,14 @@ func readTag(f reflect.StructField) (string, bool) { // // know the amount of attribute values at runtime, use a string array. // MemberOf []string `ldap:"memberOf"` // +// // ID is an integer value, it will fail unmarshaling when the given +// // attribute value cannot be parsed into an integer. +// ID int `ldap:"id"` +// +// // Data is similar to MemberOf a slice containing all attribute +// // values. +// Data []byte `ldap:"data"` +// // // This won't work, as the field is not of type string. For this // // to work, you'll have to temporarily store the result in string // // (or string array) and convert it to the desired type afterwards. @@ -254,8 +263,16 @@ func (e *Entry) Unmarshal(i interface{}) (err error) { } case string: fv.SetString(values[0]) + case []byte: + fv.SetBytes([]byte(values[0])) + case int: + intVal, err := strconv.ParseInt(values[0], 10, 32) + if err != nil { + return fmt.Errorf("ldap: could not parse value '%s' into int field", values[0]) + } + fv.SetInt(int64(intVal)) default: - return fmt.Errorf("ldap: expected field to be of type string or []string, got %v", ft.Type) + return fmt.Errorf("ldap: expected field to be of type string, []string, int or []byte, got %v", ft.Type) } } return diff --git a/search_test.go b/search_test.go index 6b0e3fbd..fcbf6063 100644 --- a/search_test.go +++ b/search_test.go @@ -86,6 +86,20 @@ func TestEntry_Unmarshal(t *testing.T) { Values: []string{"mario@go-ldap.com"}, ByteValues: nil, }, + // Tests int value. + { + Name: "id", + Values: []string{"2147483647"}, + ByteValues: nil, + }, + // Tests []byte value. + { + Name: "data", + Values: []string{"data"}, + ByteValues: [][]byte{ + []byte("data"), + }, + }, }, } @@ -93,12 +107,16 @@ func TestEntry_Unmarshal(t *testing.T) { Dn string `ldap:"dn"` Cn string `ldap:"cn"` Mail string `ldap:"mail"` + ID int `ldap:"id"` + Data []byte `ldap:"data"` } expect := &User{ Dn: "cn=mario,ou=Users,dc=go-ldap,dc=github,dc=com", Cn: "mario", Mail: "mario@go-ldap.com", + ID: 2147483647, + Data: []byte("data"), } result := &User{} err := entry.Unmarshal(result) diff --git a/v3/search.go b/v3/search.go index 5f3d47c5..fc94077b 100644 --- a/v3/search.go +++ b/v3/search.go @@ -5,6 +5,7 @@ import ( "fmt" "reflect" "sort" + "strconv" "strings" ber "github.com/go-asn1-ber/asn1-ber" @@ -184,8 +185,8 @@ func readTag(f reflect.StructField) (string, bool) { // Unmarshal parses the Entry in the value pointed to by i // // Currently, this methods only supports struct fields of type -// string or []string. Other field types will not be regarded. -// If the field type is a string but multiple attribute values +// string, []string, int or []byte. Other field types will not be regarded. +// If the field type is a string or int but multiple attribute values // are returned, the first value will be used to fill the field. // // Example: @@ -203,6 +204,14 @@ func readTag(f reflect.StructField) (string, bool) { // // know the amount of attribute values at runtime, use a string array. // MemberOf []string `ldap:"memberOf"` // +// // ID is an integer value, it will fail unmarshaling when the given +// // attribute value cannot be parsed into an integer. +// ID int `ldap:"id"` +// +// // Data is similar to MemberOf a slice containing all attribute +// // values. +// Data []byte `ldap:"data"` +// // // This won't work, as the field is not of type string. For this // // to work, you'll have to temporarily store the result in string // // (or string array) and convert it to the desired type afterwards. @@ -254,8 +263,16 @@ func (e *Entry) Unmarshal(i interface{}) (err error) { } case string: fv.SetString(values[0]) + case []byte: + fv.SetBytes([]byte(values[0])) + case int: + intVal, err := strconv.ParseInt(values[0], 10, 32) + if err != nil { + return fmt.Errorf("ldap: could not parse value '%s' into int field", values[0]) + } + fv.SetInt(int64(intVal)) default: - return fmt.Errorf("ldap: expected field to be of type string or []string, got %v", ft.Type) + return fmt.Errorf("ldap: expected field to be of type string, []string, int or []byte, got %v", ft.Type) } } return diff --git a/v3/search_test.go b/v3/search_test.go index 6b0e3fbd..fcbf6063 100644 --- a/v3/search_test.go +++ b/v3/search_test.go @@ -86,6 +86,20 @@ func TestEntry_Unmarshal(t *testing.T) { Values: []string{"mario@go-ldap.com"}, ByteValues: nil, }, + // Tests int value. + { + Name: "id", + Values: []string{"2147483647"}, + ByteValues: nil, + }, + // Tests []byte value. + { + Name: "data", + Values: []string{"data"}, + ByteValues: [][]byte{ + []byte("data"), + }, + }, }, } @@ -93,12 +107,16 @@ func TestEntry_Unmarshal(t *testing.T) { Dn string `ldap:"dn"` Cn string `ldap:"cn"` Mail string `ldap:"mail"` + ID int `ldap:"id"` + Data []byte `ldap:"data"` } expect := &User{ Dn: "cn=mario,ou=Users,dc=go-ldap,dc=github,dc=com", Cn: "mario", Mail: "mario@go-ldap.com", + ID: 2147483647, + Data: []byte("data"), } result := &User{} err := entry.Unmarshal(result) From aac249ff7fd70b37b87126ab5f93924ea5db0154 Mon Sep 17 00:00:00 2001 From: xoc Date: Mon, 27 Jun 2022 21:55:37 +0200 Subject: [PATCH 2/3] added int64 --- search.go | 15 +++++++++------ search_test.go | 28 ++++++++++++++++++---------- v3/search.go | 15 +++++++++------ v3/search_test.go | 28 ++++++++++++++++++---------- 4 files changed, 54 insertions(+), 32 deletions(-) diff --git a/search.go b/search.go index fc94077b..9bb7fcb0 100644 --- a/search.go +++ b/search.go @@ -185,9 +185,9 @@ func readTag(f reflect.StructField) (string, bool) { // Unmarshal parses the Entry in the value pointed to by i // // Currently, this methods only supports struct fields of type -// string, []string, int or []byte. Other field types will not be regarded. -// If the field type is a string or int but multiple attribute values -// are returned, the first value will be used to fill the field. +// string, []string, int, int64 or []byte. Other field types will not be +// regarded. If the field type is a string or int but multiple attribute +// values are returned, the first value will be used to fill the field. // // Example: // type UserEntry struct { @@ -208,6 +208,9 @@ func readTag(f reflect.StructField) (string, bool) { // // attribute value cannot be parsed into an integer. // ID int `ldap:"id"` // +// // LongID is similar to ID but uses an int64 instead. +// LongID int64 `ldap:"longId"` +// // // Data is similar to MemberOf a slice containing all attribute // // values. // Data []byte `ldap:"data"` @@ -265,12 +268,12 @@ func (e *Entry) Unmarshal(i interface{}) (err error) { fv.SetString(values[0]) case []byte: fv.SetBytes([]byte(values[0])) - case int: - intVal, err := strconv.ParseInt(values[0], 10, 32) + case int, int64: + intVal, err := strconv.ParseInt(values[0], 10, 64) if err != nil { return fmt.Errorf("ldap: could not parse value '%s' into int field", values[0]) } - fv.SetInt(int64(intVal)) + fv.SetInt(intVal) default: return fmt.Errorf("ldap: expected field to be of type string, []string, int or []byte, got %v", ft.Type) } diff --git a/search_test.go b/search_test.go index fcbf6063..54a3dc94 100644 --- a/search_test.go +++ b/search_test.go @@ -92,6 +92,12 @@ func TestEntry_Unmarshal(t *testing.T) { Values: []string{"2147483647"}, ByteValues: nil, }, + // Tests int64 value. + { + Name: "longId", + Values: []string{"9223372036854775807"}, + ByteValues: nil, + }, // Tests []byte value. { Name: "data", @@ -104,19 +110,21 @@ func TestEntry_Unmarshal(t *testing.T) { } type User struct { - Dn string `ldap:"dn"` - Cn string `ldap:"cn"` - Mail string `ldap:"mail"` - ID int `ldap:"id"` - Data []byte `ldap:"data"` + Dn string `ldap:"dn"` + Cn string `ldap:"cn"` + Mail string `ldap:"mail"` + ID int `ldap:"id"` + LongID int64 `ldap:"longId"` + Data []byte `ldap:"data"` } expect := &User{ - Dn: "cn=mario,ou=Users,dc=go-ldap,dc=github,dc=com", - Cn: "mario", - Mail: "mario@go-ldap.com", - ID: 2147483647, - Data: []byte("data"), + Dn: "cn=mario,ou=Users,dc=go-ldap,dc=github,dc=com", + Cn: "mario", + Mail: "mario@go-ldap.com", + ID: 2147483647, + LongID: 9223372036854775807, + Data: []byte("data"), } result := &User{} err := entry.Unmarshal(result) diff --git a/v3/search.go b/v3/search.go index fc94077b..9bb7fcb0 100644 --- a/v3/search.go +++ b/v3/search.go @@ -185,9 +185,9 @@ func readTag(f reflect.StructField) (string, bool) { // Unmarshal parses the Entry in the value pointed to by i // // Currently, this methods only supports struct fields of type -// string, []string, int or []byte. Other field types will not be regarded. -// If the field type is a string or int but multiple attribute values -// are returned, the first value will be used to fill the field. +// string, []string, int, int64 or []byte. Other field types will not be +// regarded. If the field type is a string or int but multiple attribute +// values are returned, the first value will be used to fill the field. // // Example: // type UserEntry struct { @@ -208,6 +208,9 @@ func readTag(f reflect.StructField) (string, bool) { // // attribute value cannot be parsed into an integer. // ID int `ldap:"id"` // +// // LongID is similar to ID but uses an int64 instead. +// LongID int64 `ldap:"longId"` +// // // Data is similar to MemberOf a slice containing all attribute // // values. // Data []byte `ldap:"data"` @@ -265,12 +268,12 @@ func (e *Entry) Unmarshal(i interface{}) (err error) { fv.SetString(values[0]) case []byte: fv.SetBytes([]byte(values[0])) - case int: - intVal, err := strconv.ParseInt(values[0], 10, 32) + case int, int64: + intVal, err := strconv.ParseInt(values[0], 10, 64) if err != nil { return fmt.Errorf("ldap: could not parse value '%s' into int field", values[0]) } - fv.SetInt(int64(intVal)) + fv.SetInt(intVal) default: return fmt.Errorf("ldap: expected field to be of type string, []string, int or []byte, got %v", ft.Type) } diff --git a/v3/search_test.go b/v3/search_test.go index fcbf6063..54a3dc94 100644 --- a/v3/search_test.go +++ b/v3/search_test.go @@ -92,6 +92,12 @@ func TestEntry_Unmarshal(t *testing.T) { Values: []string{"2147483647"}, ByteValues: nil, }, + // Tests int64 value. + { + Name: "longId", + Values: []string{"9223372036854775807"}, + ByteValues: nil, + }, // Tests []byte value. { Name: "data", @@ -104,19 +110,21 @@ func TestEntry_Unmarshal(t *testing.T) { } type User struct { - Dn string `ldap:"dn"` - Cn string `ldap:"cn"` - Mail string `ldap:"mail"` - ID int `ldap:"id"` - Data []byte `ldap:"data"` + Dn string `ldap:"dn"` + Cn string `ldap:"cn"` + Mail string `ldap:"mail"` + ID int `ldap:"id"` + LongID int64 `ldap:"longId"` + Data []byte `ldap:"data"` } expect := &User{ - Dn: "cn=mario,ou=Users,dc=go-ldap,dc=github,dc=com", - Cn: "mario", - Mail: "mario@go-ldap.com", - ID: 2147483647, - Data: []byte("data"), + Dn: "cn=mario,ou=Users,dc=go-ldap,dc=github,dc=com", + Cn: "mario", + Mail: "mario@go-ldap.com", + ID: 2147483647, + LongID: 9223372036854775807, + Data: []byte("data"), } result := &User{} err := entry.Unmarshal(result) From ffb0350b5aad1c7bc1f4c73a51a0f22a938dd6a3 Mon Sep 17 00:00:00 2001 From: xoc Date: Mon, 27 Jun 2022 21:57:15 +0200 Subject: [PATCH 3/3] updated error message --- search.go | 2 +- v3/search.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/search.go b/search.go index 9bb7fcb0..c174f197 100644 --- a/search.go +++ b/search.go @@ -275,7 +275,7 @@ func (e *Entry) Unmarshal(i interface{}) (err error) { } fv.SetInt(intVal) default: - return fmt.Errorf("ldap: expected field to be of type string, []string, int or []byte, got %v", ft.Type) + return fmt.Errorf("ldap: expected field to be of type string, []string, int, int64 or []byte, got %v", ft.Type) } } return diff --git a/v3/search.go b/v3/search.go index 9bb7fcb0..c174f197 100644 --- a/v3/search.go +++ b/v3/search.go @@ -275,7 +275,7 @@ func (e *Entry) Unmarshal(i interface{}) (err error) { } fv.SetInt(intVal) default: - return fmt.Errorf("ldap: expected field to be of type string, []string, int or []byte, got %v", ft.Type) + return fmt.Errorf("ldap: expected field to be of type string, []string, int, int64 or []byte, got %v", ft.Type) } } return