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

added int and []byte type to entry unmarshal #382

Merged
merged 3 commits into from
Jun 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
28 changes: 24 additions & 4 deletions search.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"reflect"
"sort"
"strconv"
"strings"

ber "github.com/go-asn1-ber/asn1-ber"
Expand Down Expand Up @@ -184,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 or []string. Other field types will not be regarded.
// If the field type is a string 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 {
Expand All @@ -203,6 +204,17 @@ 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"`
//
// // 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"`
//
// // 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.
Expand Down Expand Up @@ -254,8 +266,16 @@ func (e *Entry) Unmarshal(i interface{}) (err error) {
}
case string:
fv.SetString(values[0])
case []byte:
fv.SetBytes([]byte(values[0]))
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(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, int64 or []byte, got %v", ft.Type)
}
}
return
Expand Down
38 changes: 32 additions & 6 deletions search_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,19 +86,45 @@ 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 int64 value.
{
Name: "longId",
Values: []string{"9223372036854775807"},
ByteValues: nil,
},
// Tests []byte value.
{
Name: "data",
Values: []string{"data"},
ByteValues: [][]byte{
[]byte("data"),
},
},
},
}

type User struct {
Dn string `ldap:"dn"`
Cn string `ldap:"cn"`
Mail string `ldap:"mail"`
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",
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)
Expand Down
28 changes: 24 additions & 4 deletions v3/search.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"reflect"
"sort"
"strconv"
"strings"

ber "github.com/go-asn1-ber/asn1-ber"
Expand Down Expand Up @@ -184,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 or []string. Other field types will not be regarded.
// If the field type is a string 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 {
Expand All @@ -203,6 +204,17 @@ 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"`
//
// // 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"`
//
// // 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.
Expand Down Expand Up @@ -254,8 +266,16 @@ func (e *Entry) Unmarshal(i interface{}) (err error) {
}
case string:
fv.SetString(values[0])
case []byte:
fv.SetBytes([]byte(values[0]))
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(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, int64 or []byte, got %v", ft.Type)
}
}
return
Expand Down
38 changes: 32 additions & 6 deletions v3/search_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,19 +86,45 @@ 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 int64 value.
{
Name: "longId",
Values: []string{"9223372036854775807"},
ByteValues: nil,
},
// Tests []byte value.
{
Name: "data",
Values: []string{"data"},
ByteValues: [][]byte{
[]byte("data"),
},
},
},
}

type User struct {
Dn string `ldap:"dn"`
Cn string `ldap:"cn"`
Mail string `ldap:"mail"`
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",
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)
Expand Down