nebius/SWE-rebench-V2-PRs huggingface dataset:
Repository: argoproj/argo
Pull request #3659 (2020-08-03 17:00:39)

fix: interface{} values should be expanded with '%v'
Fixes: https://github.com/argoproj/argo/issues/3647

alexec: I think this might also fix #3653 ?

Patch:
diff --git a/workflow/controller/operator.go b/workflow/controller/operator.go
index 243cf31ba..f0c3c9203 100644
--- a/workflow/controller/operator.go
+++ b/workflow/controller/operator.go
@@ -2487,7 +2487,7 @@ func processItem(fstTmpl *fasttemplate.Template, name string, index int, item wf
 		mapVal := item.GetMapVal()
 		for itemKey, itemVal := range mapVal {
 			replaceMap[fmt.Sprintf("item.%s", itemKey)] = fmt.Sprintf("%v", itemVal)
-			vals = append(vals, fmt.Sprintf("%s:%s", itemKey, itemVal))
+			vals = append(vals, fmt.Sprintf("%s:%v", itemKey, itemVal))
 
 		}
 		jsonByteVal, err := json.Marshal(mapVal)


Test patch:
diff --git a/workflow/controller/operator_test.go b/workflow/controller/operator_test.go
index af6b55caa..6d166478a 100644
--- a/workflow/controller/operator_test.go
+++ b/workflow/controller/operator_test.go
@@ -9,12 +9,11 @@ import (
 	"testing"
 	"time"
 
-	"github.com/argoproj/argo/workflow/controller/cache"
-
 	"github.com/prometheus/client_golang/prometheus"
 	dto "github.com/prometheus/client_model/go"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
+	"github.com/valyala/fasttemplate"
 	apiv1 "k8s.io/api/core/v1"
 	apierr "k8s.io/apimachinery/pkg/api/errors"
 	"k8s.io/apimachinery/pkg/api/resource"
@@ -27,6 +26,7 @@ import (
 	wfv1 "github.com/argoproj/argo/pkg/apis/workflow/v1alpha1"
 	"github.com/argoproj/argo/test"
 	"github.com/argoproj/argo/workflow/common"
+	"github.com/argoproj/argo/workflow/controller/cache"
 	hydratorfake "github.com/argoproj/argo/workflow/hydrator/fake"
 	"github.com/argoproj/argo/workflow/util"
 )
@@ -4581,3 +4581,23 @@ func TestFailSuspendedAndPendingNodesAfterShutdown(t *testing.T) {
 		}
 	})
 }
+
+func TestProcessItem(t *testing.T) {
+	task := wfv1.DAGTask{
+		WithParam: `[{"number": 2, "string": "foo", "list": [0, "1"], "json": {"number": 2, "string": "foo", "list": [0, "1"]}}]`,
+	}
+	taskBytes, err := json.Marshal(task)
+	assert.NoError(t, err)
+	fstTmpl, err := fasttemplate.NewTemplate(string(taskBytes), "{{", "}}")
+	assert.NoError(t, err)
+
+	var items []wfv1.Item
+	err = json.Unmarshal([]byte(task.WithParam), &items)
+	assert.NoError(t, err)
+
+	var newTask wfv1.DAGTask
+	newTaskName, err := processItem(fstTmpl, "task-name", 0, items[0], &newTask)
+	if assert.NoError(t, err) {
+		assert.Equal(t, `task-name(0:json:map[list:[0 1] number:2 string:foo],list:[0 1],number:2,string:foo)`, newTaskName)
+	}
+}
Repository: google/go-tpm
Pull request #323 (2023-04-03 21:17:04)

Accept *ecdsa.PublicKey and transmute to *ecdh.PublicKey


Patch:
diff --git a/tpm2/credactivation/credential_activation.go b/tpm2/credactivation/credential_activation.go
index e46b28f..46c935c 100644
--- a/tpm2/credactivation/credential_activation.go
+++ b/tpm2/credactivation/credential_activation.go
@@ -21,6 +21,7 @@ import (
 	"crypto/aes"
 	"crypto/cipher"
 	"crypto/ecdh"
+	"crypto/ecdsa"
 	"crypto/hmac"
 	"crypto/rand"
 	"crypto/rsa"
@@ -63,6 +64,12 @@ func generate(aik *tpm2.HashValue, pub crypto.PublicKey, symBlockSize int, secre
 		if err != nil {
 			return nil, nil, fmt.Errorf("creating seed: %v", err)
 		}
+	case *ecdsa.PublicKey:
+		ecdhKey, err := ekKey.ECDH()
+		if err != nil {
+			return nil, nil, fmt.Errorf("transmuting ecdsa key to ecdh key: %v", err)
+		}
+		return generate(aik, ecdhKey, symBlockSize, secret, rnd)
 	case *rsa.PublicKey:
 		seed, encSecret, err = createRSASeed(aik, ekKey, symBlockSize, rnd)
 		if err != nil {


Test patch:
diff --git a/tpm2/credactivation/credential_activation_test.go b/tpm2/credactivation/credential_activation_test.go
index b2ed8ff..891384c 100644
--- a/tpm2/credactivation/credential_activation_test.go
+++ b/tpm2/credactivation/credential_activation_test.go
@@ -16,7 +16,6 @@ package credactivation
 
 import (
 	"bytes"
-	"crypto/ecdsa"
 	"crypto/x509"
 	"encoding/base64"
 	"encoding/pem"
@@ -80,13 +79,6 @@ func TestCredentialActivation(t *testing.T) {
 			t.Fatal(err)
 		}
 
-		if ecdsaPub, ok := public.(*ecdsa.PublicKey); ok {
-			public, err = ecdsaPub.ECDH()
-			if err != nil {
-				t.Fatal(err)
-			}
-		}
-
 		aikDigest := mustDecodeBase64("5snpf9qRfKD2Tb72eLAZqC/a/MyUhg+IvdwDZkTJK9w=", t)
 		expected := mustDecodeBase64(test.expected, t)
 		secret := mustDecodeBase64("AQIDBAUGBwgBAgMEBQYHCAECAwQFBgcIAQIDBAUGBwg=", t)
Repository: skiptests/astraea
Pull request #366 (2022-05-26 03:41:52)

The build is broken after we rename availablePartitionLeaders to availableReplicaLeaders
https://github.com/skiptests/astraea/commit/6a6135cd0ed5df788e87311c2b9ef2eb9257aa51 breaks the build, and it is caused by https://github.com/skiptests/astraea/commit/0840f87daed9c48825782c0f30a09d06c56d780e which renamed some APIs


Patch:
diff --git a/app/src/main/java/org/astraea/partitioner/smooth/SmoothWeightRoundRobin.java b/app/src/main/java/org/astraea/partitioner/smooth/SmoothWeightRoundRobin.java
index 83e6172c..32887eeb 100644
--- a/app/src/main/java/org/astraea/partitioner/smooth/SmoothWeightRoundRobin.java
+++ b/app/src/main/java/org/astraea/partitioner/smooth/SmoothWeightRoundRobin.java
@@ -86,7 +86,7 @@ public final class SmoothWeightRoundRobin
         brokersIDofTopic.computeIfAbsent(
             topic,
             e ->
-                clusterInfo.availablePartitionLeaders(topic).stream()
+                clusterInfo.availableReplicaLeaders(topic).stream()
                     .map(replicaInfo -> replicaInfo.nodeInfo().id())
                     .collect(Collectors.toList()));
     this.currentWeight =


Test patch:
diff --git a/app/src/test/java/org/astraea/partitioner/smooth/SmoothWeightRoundRobinDispatchTest.java b/app/src/test/java/org/astraea/partitioner/smooth/SmoothWeightRoundRobinDispatchTest.java
index aaa68993..06ee2aa6 100644
--- a/app/src/test/java/org/astraea/partitioner/smooth/SmoothWeightRoundRobinDispatchTest.java
+++ b/app/src/test/java/org/astraea/partitioner/smooth/SmoothWeightRoundRobinDispatchTest.java
@@ -296,7 +296,7 @@ public class SmoothWeightRoundRobinDispatchTest extends RequireBrokerCluster {
     var testCluster =
         new FakeClusterInfo() {
           @Override
-          public List<ReplicaInfo> availablePartitionLeaders(String topic) {
+          public List<ReplicaInfo> availableReplicaLeaders(String topic) {
             return List.of(re1, re2, re3);
           }
         };
diff --git a/app/src/test/java/org/astraea/partitioner/smooth/SmoothWeightRoundRobinTest.java b/app/src/test/java/org/astraea/partitioner/smooth/SmoothWeightRoundRobinTest.java
index 33601de0..1fd6de80 100644
--- a/app/src/test/java/org/astraea/partitioner/smooth/SmoothWeightRoundRobinTest.java
+++ b/app/src/test/java/org/astraea/partitioner/smooth/SmoothWeightRoundRobinTest.java
@@ -58,7 +58,7 @@ public class SmoothWeightRoundRobinTest {
     Mockito.when(node3.id()).thenReturn(3);
     return new FakeClusterInfo() {
       @Override
-      public List<ReplicaInfo> availablePartitionLeaders(String topic) {
+      public List<ReplicaInfo> availableReplicaLeaders(String topic) {
         return List.of(re1, re2, re3);
       }
     };
Repository: GoogleCloudPlatform/spark-on-k8s-operator
Pull request #1234 (2021-04-20 17:11:38)

Link to Kubernetes Slack
Make it easier for new users to get to the slack channel.


Patch:
diff --git a/README.md b/README.md
index 0ca7e32..c2ba75f 100644
--- a/README.md
+++ b/README.md
@@ -5,7 +5,7 @@
 
 ## Community
 
-* Join our [Slack](https://kubernetes.slack.com/messages/CALBDHMTL) channel.
+* Join our [Slack](https://kubernetes.slack.com/messages/CALBDHMTL) channel on [Kubernetes on Slack](https://slack.k8s.io/).
 * Check out [who is using the Kubernetes Operator for Apache Spark](docs/who-is-using.md).
 
 ## Project Status
diff --git a/pkg/webhook/patch.go b/pkg/webhook/patch.go
index 14c4fe7..a6f54f6 100644
--- a/pkg/webhook/patch.go
+++ b/pkg/webhook/patch.go
@@ -560,6 +560,7 @@ func addPriorityClassName(pod *corev1.Pod, app *v1beta2.SparkApplication) []patc
 
 		if pod.Spec.Priority != nil {
 			ops = append(ops, patchOperation{Op: "remove", Path: "/spec/priority"})
+			ops = append(ops, patchOperation{Op: "remove", Path: "/spec/preemptionPolicy"})
 		}
 	}
 


Test patch:
diff --git a/pkg/webhook/patch_test.go b/pkg/webhook/patch_test.go
index 8db4fbb..b68585c 100644
--- a/pkg/webhook/patch_test.go
+++ b/pkg/webhook/patch_test.go
@@ -823,6 +823,7 @@ func TestPatchSparkPod_PriorityClassName(t *testing.T) {
 	assert.Equal(t, priorityClassName, modifiedDriverPod.Spec.PriorityClassName)
 
 	var defaultPriority int32 = 0
+	var defaultPolicy corev1.PreemptionPolicy = corev1.PreemptLowerPriority
 	executorPod := &corev1.Pod{
 		ObjectMeta: metav1.ObjectMeta{
 			Name: "spark-executor",
@@ -838,7 +839,8 @@ func TestPatchSparkPod_PriorityClassName(t *testing.T) {
 					Image: "spark-executor:latest",
 				},
 			},
-			Priority: &defaultPriority,
+			Priority:         &defaultPriority,
+			PreemptionPolicy: &defaultPolicy,
 		},
 	}
 
@@ -849,6 +851,7 @@ func TestPatchSparkPod_PriorityClassName(t *testing.T) {
 	//Executor priorityClassName should also be populated when specified in SparkApplicationSpec
 	assert.Equal(t, priorityClassName, modifiedExecutorPod.Spec.PriorityClassName)
 	assert.Nil(t, modifiedExecutorPod.Spec.Priority)
+	assert.Nil(t, modifiedExecutorPod.Spec.PreemptionPolicy)
 }
 
 func TestPatchSparkPod_Sidecars(t *testing.T) {
Repository: not-fl3/nanoserde
Pull request #59 (2023-07-09 01:00:22)

add fixed-len array and i8 serde impls (with test)
Noticed while adding nanoserde to the rust serialization benchmark repo that fixed-length arrays and `i8`s were not  being handled. 


Patch:
diff --git a/src/serde_bin.rs b/src/serde_bin.rs
index 0f2c8d9..5dfd76e 100644
--- a/src/serde_bin.rs
+++ b/src/serde_bin.rs
@@ -127,6 +127,7 @@ impl_ser_de_bin_for!(u32);
 impl_ser_de_bin_for!(i32);
 impl_ser_de_bin_for!(u16);
 impl_ser_de_bin_for!(i16);
+impl_ser_de_bin_for!(i8);
 
 impl SerBin for usize {
     fn ser_bin(&self, s: &mut Vec<u8>) {
@@ -383,6 +384,16 @@ where
     }
 }
 
+impl<T, const N: usize> SerBin for [T; N]
+where
+    T: SerBin,
+{
+    #[inline(always)]
+    fn ser_bin(&self, s: &mut Vec<u8>) {
+        self.as_slice().ser_bin(s)
+    }
+}
+
 impl<T, const N: usize> DeBin for [T; N]
 where
     T: DeBin,
diff --git a/src/serde_json.rs b/src/serde_json.rs
index 993abd6..7e69d8d 100644
--- a/src/serde_json.rs
+++ b/src/serde_json.rs
@@ -974,6 +974,16 @@ where
     }
 }
 
+impl<T, const N: usize> SerJson for [T; N]
+where
+    T: SerJson,
+{
+    #[inline(always)]
+    fn ser_json(&self, d: usize, s: &mut SerJsonState) {
+        self.as_slice().ser_json(d, s)
+    }
+}
+
 impl<T, const N: usize> DeJson for [T; N]
 where
     T: DeJson,
diff --git a/src/serde_ron.rs b/src/serde_ron.rs
index 39972c5..867d88d 100644
--- a/src/serde_ron.rs
+++ b/src/serde_ron.rs
@@ -1011,6 +1011,16 @@ where
     }
 }
 
+impl<T, const N: usize> SerRon for [T; N]
+where
+    T: SerRon,
+{
+    #[inline(always)]
+    fn ser_ron(&self, d: usize, s: &mut SerRonState) {
+        self.as_slice().ser_ron(d, s)
+    }
+}
+
 unsafe fn de_ron_array_impl_inner<T>(
     top: *mut T,
     count: usize,


Test patch:
diff --git a/tests/ser_de.rs b/tests/ser_de.rs
index d4b32ae..bdbb53c 100644
--- a/tests/ser_de.rs
+++ b/tests/ser_de.rs
@@ -11,6 +11,7 @@ fn ser_de() {
         c: Option<String>,
         d: Option<String>,
         e: Option<HashMap<String, String>>,
+        f: Option<([u32; 4], String)>,
     }
 
     let mut map = HashMap::new();
@@ -22,6 +23,7 @@ fn ser_de() {
         c: Some("asd".to_string()),
         d: None,
         e: Some(map),
+        f: Some(([1, 2, 3, 4], "tuple".to_string())),
     };
 
     let bytes = SerBin::serialize_bin(&test);
Repository: not-fl3/nanoserde
Pull request #74 (2023-08-06 14:42:12)

add serialization of unit type
Adding serde of unit type to ron and bin, and updating the json version to output valid json (and also matching [serde's behavior](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=d641466cd567ad9bc597ea5cd80e09e2)). Demonstrated with a test that unit type serde was not working correctly in json previously.


Patch:
diff --git a/src/serde_bin.rs b/src/serde_bin.rs
index 5dfd76e..556541b 100644
--- a/src/serde_bin.rs
+++ b/src/serde_bin.rs
@@ -410,6 +410,20 @@ where
     }
 }
 
+impl SerBin for () {
+    #[inline(always)]
+    fn ser_bin(&self, _s: &mut Vec<u8>) {
+        // do nothing
+    }
+}
+
+impl DeBin for () {
+    #[inline(always)]
+    fn de_bin(_o: &mut usize, _d: &[u8]) -> Result<Self, DeBinErr> {
+        Ok(())
+    }
+}
+
 impl<A, B> SerBin for (A, B)
 where
     A: SerBin,
diff --git a/src/serde_json.rs b/src/serde_json.rs
index bdd7b2d..6bff6f3 100644
--- a/src/serde_json.rs
+++ b/src/serde_json.rs
@@ -748,15 +748,18 @@ where
 
 impl SerJson for () {
     fn ser_json(&self, _d: usize, s: &mut SerJsonState) {
-        s.out.push_str("")
+        s.out.push_str("null")
     }
 }
 
 impl DeJson for () {
     fn de_json(s: &mut DeJsonState, i: &mut Chars) -> Result<(), DeJsonErr> {
-        // skip ""
-        s.next_tok(i)?;
-        return Ok(());
+        if let DeJsonTok::Null = s.tok {
+            s.next_tok(i)?;
+            return Ok(());
+        } else {
+            return Err(s.err_token("null"));
+        }
     }
 }
 
diff --git a/src/serde_ron.rs b/src/serde_ron.rs
index 867d88d..c768545 100644
--- a/src/serde_ron.rs
+++ b/src/serde_ron.rs
@@ -1062,6 +1062,20 @@ where
     t
 }
 
+impl SerRon for () {
+    fn ser_ron(&self, _d: usize, s: &mut SerRonState) {
+        s.out.push_str("()");
+    }
+}
+
+impl DeRon for () {
+    fn de_ron(s: &mut DeRonState, i: &mut Chars) -> Result<(), DeRonErr> {
+        s.paren_open(i)?;
+        s.paren_close(i)?;
+        Ok(())
+    }
+}
+
 impl<A, B> SerRon for (A, B)
 where
     A: SerRon,


Test patch:
diff --git a/tests/ser_de.rs b/tests/ser_de.rs
index 860e3d4..34a9c09 100644
--- a/tests/ser_de.rs
+++ b/tests/ser_de.rs
@@ -12,6 +12,7 @@ fn ser_de() {
         d: Option<String>,
         e: Option<HashMap<String, String>>,
         f: Option<([u32; 4], String)>,
+        g: (),
     }
 
     let mut map = HashMap::new();
@@ -24,6 +25,7 @@ fn ser_de() {
         d: None,
         e: Some(map),
         f: Some(([1, 2, 3, 4], "tuple".to_string())),
+        g: (),
     };
 
     let bytes = SerBin::serialize_bin(&test);
Repository: not-fl3/nanoserde
Pull request #87 (2023-11-04 17:51:21)

Exclude self bounds
Excludes an illegal bound type from being applied by the proc macro


Patch:
diff --git a/derive/src/shared.rs b/derive/src/shared.rs
index f5ddb2c..aa4948e 100644
--- a/derive/src/shared.rs
+++ b/derive/src/shared.rs
@@ -73,7 +73,7 @@ pub(crate) fn struct_bounds_strings(struct_: &Struct, bound_name: &str) -> (Stri
         return ("".to_string(), "".to_string());
     }
     let mut generic_w_bounds = "<".to_string();
-    for generic in generics.iter() {
+    for generic in generics.iter().filter(|g| g.ident_only() != "Self") {
         generic_w_bounds += generic
             .full_with_const(&[format!("nanoserde::{}", bound_name).as_str()], true)
             .as_str();
@@ -82,7 +82,7 @@ pub(crate) fn struct_bounds_strings(struct_: &Struct, bound_name: &str) -> (Stri
     generic_w_bounds += ">";
 
     let mut generic_no_bounds = "<".to_string();
-    for generic in generics.iter() {
+    for generic in generics.iter().filter(|g| g.ident_only() != "Self") {
         generic_no_bounds += generic.ident_only().as_str();
         generic_no_bounds += ", ";
     }
@@ -97,7 +97,7 @@ pub(crate) fn enum_bounds_strings(enum_: &Enum, bound_name: &str) -> (String, St
         return ("".to_string(), "".to_string());
     }
     let mut generic_w_bounds = "<".to_string();
-    for generic in generics.iter() {
+    for generic in generics.iter().filter(|g| g.ident_only() != "Self") {
         generic_w_bounds += generic
             .full_with_const(&[format!("nanoserde::{}", bound_name).as_str()], true)
             .as_str();
@@ -106,7 +106,7 @@ pub(crate) fn enum_bounds_strings(enum_: &Enum, bound_name: &str) -> (String, St
     generic_w_bounds += ">";
 
     let mut generic_no_bounds = "<".to_string();
-    for generic in generics.iter() {
+    for generic in generics.iter().filter(|g| g.ident_only() != "Self") {
         generic_no_bounds += generic.ident_only().as_str();
         generic_no_bounds += ", ";
     }


Test patch:
diff --git a/tests/bin.rs b/tests/bin.rs
index d3d88da..355c020 100644
--- a/tests/bin.rs
+++ b/tests/bin.rs
@@ -119,6 +119,30 @@ fn field_proxy() {
     assert!(test == test_deserialized);
 }
 
+#[test]
+fn field_ignore_self_bound() {
+    #[derive(SerBin)]
+    pub struct Serializable<'a>
+    where
+        Self: 'a,
+    {
+        foo: &'a i32,
+    }
+
+    #[derive(DeBin)]
+    pub struct DeSerializable {
+        foo: i32,
+    }
+
+    let foo_base = 42;
+
+    let test = Serializable { foo: &42 };
+
+    let bytes = SerBin::serialize_bin(&test);
+    let deser: DeSerializable = DeBin::deserialize_bin(&bytes).unwrap();
+    assert_eq!(foo_base, deser.foo);
+}
+
 #[test]
 fn struct_proxy() {
     #[derive(PartialEq, Debug)]
Repository: not-fl3/nanoserde
Pull request #131 (2025-05-10 17:14:00)

Add the Carriage Return to ident_term_chars
When parsing for identifiers it included the carriage return, throwing a "`Cannot parse toml tokenizer`" toml error instead of ignoring it, most noticeable with boolean values

E.g.
````rust
[src\main.rs:55:5] TomlParser::parse("public = false\r\n") = Err(
    Toml error: Cannot parse toml tokenizer , line:1 col:1,
)
````

This fixes that, while also adding a test for carriage returns


knickish: I'm pretty sure this makes `\r` by itself a valid ending to an ident, which seems not legal?
Kyryh: > I'm pretty sure this makes `\r` by itself a valid ending to an ident, which seems not legal?

I'd say it isn't much of an issue since:
- carriage returns were already checked while parsing tokens ([here](https://github.com/not-fl3/nanoserde/blob/f0a1936869fdcd4298440ae5973010cb28e39b6c/src/toml.rs#L419) and [here](https://github.com/not-fl3/nanoserde/blob/f0a1936869fdcd4298440ae5973010cb28e39b6c/src/toml.rs#L451)), just not with idents
- CR are typically followed by LF right after, so it wouldn't break anything that isn't already broken by a \n (..if that makes any sense)
knickish: Alright, sounds good 👍 

Patch:
diff --git a/src/toml.rs b/src/toml.rs
index b512c45..5dcfea5 100644
--- a/src/toml.rs
+++ b/src/toml.rs
@@ -37,7 +37,7 @@ macro_rules! ident_chars {
 /// Pattern matching a character that can terminate a valid ident.
 macro_rules! ident_term_chars {
     () => {
-        ' ' | '\t' | '\n' | '\0' | '=' | ']'
+        ' ' | '\t' | '\r' | '\n' | '\0' | '=' | ']'
     };
 }
 


Test patch:
diff --git a/tests/toml.rs b/tests/toml.rs
index 05389a3..b6c3428 100644
--- a/tests/toml.rs
+++ b/tests/toml.rs
@@ -113,3 +113,12 @@ fn toml_key_chars() {
         ])
     );
 }
+
+#[test]
+fn carriage_return() {
+    let toml_str = "foo = 1\r\nbar = false\r\n";
+    let toml = TomlParser::parse(toml_str).unwrap();
+
+    assert_eq!(toml["foo"].num(), 1.0);
+    assert_eq!(toml["bar"].boolean(), false);
+}
Repository: not-fl3/nanoserde
Pull request #139 (2025-06-11 02:35:17)

Impl `SerJson` + `DeJson` for `HashMap`s with custom hashers
 * This makes crates like `fxhash` usable with `nanoserde`
 * Add test verifying that hashmaps with custom hashers can be serialized + deserialized to/from JSON


Patch:
diff --git a/src/serde_json.rs b/src/serde_json.rs
index 03ff695..4faaaea 100644
--- a/src/serde_json.rs
+++ b/src/serde_json.rs
@@ -1203,7 +1203,7 @@ where
 }
 
 #[cfg(feature = "std")]
-impl<K, V> SerJson for std::collections::HashMap<K, V>
+impl<K, V, S> SerJson for std::collections::HashMap<K, V, S>
 where
     K: SerJson,
     V: SerJson,
@@ -1226,13 +1226,14 @@ where
 }
 
 #[cfg(feature = "std")]
-impl<K, V> DeJson for std::collections::HashMap<K, V>
+impl<K, V, S> DeJson for std::collections::HashMap<K, V, S>
 where
     K: DeJson + Eq + core::hash::Hash,
     V: DeJson,
+    S: core::hash::BuildHasher + Default,
 {
     fn de_json(s: &mut DeJsonState, i: &mut Chars) -> Result<Self, DeJsonErr> {
-        let mut h = std::collections::HashMap::new();
+        let mut h = std::collections::HashMap::with_hasher(S::default());
         s.curly_open(i)?;
         while s.tok != DeJsonTok::CurlyClose {
             let k = DeJson::de_json(s, i)?;


Test patch:
diff --git a/tests/json.rs b/tests/json.rs
index 5aa8a4a..e8db807 100644
--- a/tests/json.rs
+++ b/tests/json.rs
@@ -588,6 +588,30 @@ fn hashmaps() {
     assert_eq!(foo.map["qwe"], 2);
 }
 
+#[cfg(feature = "std")]
+#[test]
+fn serialize_hashmap_with_custom_hasher() {
+    use std::collections::hash_map::DefaultHasher;
+    use std::hash::BuildHasherDefault;
+
+    #[derive(DeJson, SerJson, Debug)]
+    struct CustomHasherMap {
+        map: HashMap<String, usize, BuildHasherDefault<DefaultHasher>>,
+    }
+
+    let mut map = CustomHasherMap {
+        map: HashMap::default(),
+    };
+    map.map.insert("key1".to_string(), 1);
+    map.map.insert("key2".to_string(), 2);
+
+    let json = SerJson::serialize_json(&map);
+    let deserialized: CustomHasherMap = DeJson::deserialize_json(&json).unwrap();
+
+    assert_eq!(deserialized.map["key1"], 1);
+    assert_eq!(deserialized.map["key2"], 2);
+}
+
 #[test]
 fn exponents() {
     #[derive(DeJson)]