Repository: pion/mediadevices
Pull request #191 (2020-06-22 00:50:00)

Add IsFloat, IsBigEndian, and IsInterleaved props
Changes:
* Add bool constraint
* Add IsFloat, IsBigEndian, and IsInterleaved properties

I didn't implement BoolRange or BoolOneOf because they're not necessary since it's only a binary option, it can be done with just Bool.


Patch:
diff --git a/pkg/prop/bool.go b/pkg/prop/bool.go
new file mode 100644
index 0000000..e585c91
--- /dev/null
+++ b/pkg/prop/bool.go
@@ -0,0 +1,30 @@
+package prop
+
+// BoolConstraint is an interface to represent bool value constraint.
+type BoolConstraint interface {
+	Compare(bool) (float64, bool)
+	Value() bool
+}
+
+// BoolExact specifies exact bool value.
+type BoolExact bool
+
+// Compare implements BoolConstraint.
+func (b BoolExact) Compare(o bool) (float64, bool) {
+	if bool(b) == o {
+		return 0.0, true
+	}
+	return 1.0, false
+}
+
+// Value implements BoolConstraint.
+func (b BoolExact) Value() bool { return bool(b) }
+
+// Bool specifies ideal bool value.
+type Bool BoolExact
+
+// Compare implements BoolConstraint.
+func (b Bool) Compare(o bool) (float64, bool) {
+	dist, _ := BoolExact(b).Compare(o)
+	return dist, true
+}
diff --git a/pkg/prop/prop.go b/pkg/prop/prop.go
index ba3b8d0..738a6d2 100644
--- a/pkg/prop/prop.go
+++ b/pkg/prop/prop.go
@@ -89,6 +89,8 @@ func (p *Media) MergeConstraints(o MediaConstraints) {
 			if v, ok := c.Value(); ok {
 				fieldA.Set(reflect.ValueOf(v))
 			}
+		case BoolConstraint:
+			fieldA.Set(reflect.ValueOf(c.Value()))
 		default:
 			panic("unsupported property type")
 		}
@@ -106,6 +108,9 @@ func (p *MediaConstraints) FitnessDistance(o Media) (float64, bool) {
 	cmps.add(p.SampleRate, o.SampleRate)
 	cmps.add(p.Latency, o.Latency)
 	cmps.add(p.ChannelCount, o.ChannelCount)
+	cmps.add(p.IsBigEndian, o.IsBigEndian)
+	cmps.add(p.IsFloat, o.IsFloat)
+	cmps.add(p.IsInterleaved, o.IsInterleaved)
 
 	return cmps.fitnessDistance()
 }
@@ -161,6 +166,12 @@ func (c *comparisons) fitnessDistance() (float64, bool) {
 			} else {
 				panic("wrong type of actual value")
 			}
+		case BoolConstraint:
+			if actual, typeOK := field.actual.(bool); typeOK {
+				d, ok = c.Compare(actual)
+			} else {
+				panic("wrong type of actual value")
+			}
 		default:
 			panic("unsupported constraint type")
 		}
@@ -188,16 +199,22 @@ type Video struct {
 
 // AudioConstraints represents an audio's constraints
 type AudioConstraints struct {
-	ChannelCount IntConstraint
-	Latency      DurationConstraint
-	SampleRate   IntConstraint
-	SampleSize   IntConstraint
+	ChannelCount  IntConstraint
+	Latency       DurationConstraint
+	SampleRate    IntConstraint
+	SampleSize    IntConstraint
+	IsBigEndian   BoolConstraint
+	IsFloat       BoolConstraint
+	IsInterleaved BoolConstraint
 }
 
 // Audio represents an audio's constraints
 type Audio struct {
-	ChannelCount int
-	Latency      time.Duration
-	SampleRate   int
-	SampleSize   int
+	ChannelCount  int
+	Latency       time.Duration
+	SampleRate    int
+	SampleSize    int
+	IsBigEndian   bool
+	IsFloat       bool
+	IsInterleaved bool
 }


Test patch:
diff --git a/pkg/prop/prop_test.go b/pkg/prop/prop_test.go
index 8230e74..691c19f 100644
--- a/pkg/prop/prop_test.go
+++ b/pkg/prop/prop_test.go
@@ -139,6 +139,24 @@ func TestCompareMatch(t *testing.T) {
 			}},
 			true,
 		},
+		"BoolExactUnmatch": {
+			MediaConstraints{AudioConstraints: AudioConstraints{
+				IsFloat: BoolExact(true),
+			}},
+			Media{Audio: Audio{
+				IsFloat: false,
+			}},
+			false,
+		},
+		"BoolExactMatch": {
+			MediaConstraints{AudioConstraints: AudioConstraints{
+				IsFloat: BoolExact(true),
+			}},
+			Media{Audio: Audio{
+				IsFloat: true,
+			}},
+			true,
+		},
 	}
 
 	for name, testData := range testDataSet {