| 
					
				 | 
			
			
				@@ -118,6 +118,52 @@ pub async fn lindex(conn: &Connection, args: &[Bytes]) -> Result<Value, Error> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+pub async fn linsert(conn: &Connection, args: &[Bytes]) -> Result<Value, Error> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    let is_before = if check_arg!(args, 2, "BEFORE") { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        true 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } else if check_arg!(args, 2, "AFTER") { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        false 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return Err(Error::Syntax); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    conn.db().get_map_or( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        &args[1], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        |v| match v { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Value::List(x) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                let pivot = checksum::Value::new(args[3].clone()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                let mut x = x.write(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                let mut found = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                for (key, val) in x.iter().enumerate() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    if *val == pivot { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        let id = if is_before { key } else { key + 1 }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        let value = checksum::Value::new(args[4].clone()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        if id > x.len() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            x.push_back(value); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            x.insert(id as usize, value); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        found = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if found { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    Ok((x.len() as i64).into()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    Ok((-1).into()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            _ => Err(Error::WrongType), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        || Ok(0.into()), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 pub async fn llen(conn: &Connection, args: &[Bytes]) -> Result<Value, Error> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     conn.db().get_map_or( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         &args[1], 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -139,6 +185,80 @@ pub async fn lpop(conn: &Connection, args: &[Bytes]) -> Result<Value, Error> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     remove_element(conn, &args[1], count, true) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+pub async fn lpos(conn: &Connection, args: &[Bytes]) -> Result<Value, Error> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    let mut index = 3; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    let element = checksum::Value::new(args[2].clone()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    let rank = if check_arg!(args, index, "RANK") { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        index += 2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Some(bytes_to_number::<usize>(&args[index - 1])?) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        None 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    let count = if check_arg!(args, index, "COUNT") { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        index += 2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Some(bytes_to_number::<usize>(&args[index - 1])?) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        None 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    let max_len = if check_arg!(args, index, "MAXLEN") { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        index += 2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        bytes_to_number::<i64>(&args[index - 1])? 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        -1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if index != args.len() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return Err(Error::Syntax); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    conn.db().get_map_or( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        &args[1], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        |v| match v { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Value::List(x) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                let x = x.read(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                let mut ret: Vec<Value> = vec![]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                for (i, val) in x.iter().enumerate() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    if *val == element { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        // Match! 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        if let Some(count) = count { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            ret.push((i as i64).into()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            if ret.len() > count { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                return Ok(ret.into()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        } else if let Some(rank) = rank { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            ret.push((i as i64).into()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            if ret.len() == rank { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                return Ok(ret[rank - 1].clone()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            // return first match! 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            return Ok((i as i64).into()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    if (i as i64) == max_len { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if count.is_some() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    Ok(ret.into()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    Ok(Value::Null) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            _ => Err(Error::WrongType), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        || { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Ok(if count.is_some() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                Value::Array(vec![]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                Value::Null 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 pub async fn lpush(conn: &Connection, args: &[Bytes]) -> Result<Value, Error> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     let is_push_x = check_arg!(args, 0, "LPUSHX"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -248,6 +368,7 @@ pub async fn rpush(conn: &Connection, args: &[Bytes]) -> Result<Value, Error> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 mod test { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     use crate::{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         cmd::test::{create_connection, run_command}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        error::Error, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         value::Value, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     use tokio::time::{sleep, Duration, Instant}; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -422,6 +543,119 @@ mod test { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     #[tokio::test] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    async fn linsert_syntax_err() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let c = create_connection(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        assert_eq!( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Ok(Value::Integer(2)), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            run_command(&c, &["rpush", "foo", "hello", "world"]).await 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        assert_eq!( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Err(Error::Syntax), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            run_command(&c, &["linsert", "foo", "beforex", "world", "there"]).await 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    #[tokio::test] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    async fn linsert_before() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let c = create_connection(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        assert_eq!( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Ok(Value::Integer(2)), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            run_command(&c, &["rpush", "foo", "hello", "world"]).await 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        assert_eq!( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Ok(Value::Integer(3)), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            run_command(&c, &["linsert", "foo", "before", "world", "there"]).await 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        assert_eq!( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Ok(Value::Array(vec![ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                Value::Blob("hello".into()), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                Value::Blob("there".into()), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                Value::Blob("world".into()), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ])), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            run_command(&c, &["lrange", "foo", "0", "-1"]).await, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    #[tokio::test] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    async fn linsert_after() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let c = create_connection(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        assert_eq!( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Ok(Value::Integer(2)), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            run_command(&c, &["rpush", "foo", "hello", "world"]).await 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        assert_eq!( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Ok(Value::Integer(3)), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            run_command(&c, &["linsert", "foo", "after", "world", "there"]).await 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        assert_eq!( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Ok(Value::Array(vec![ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                Value::Blob("hello".into()), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                Value::Blob("world".into()), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                Value::Blob("there".into()), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ])), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            run_command(&c, &["lrange", "foo", "0", "-1"]).await, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    #[tokio::test] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    async fn linsert_before_after() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let c = create_connection(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        assert_eq!( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Ok(Value::Integer(2)), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            run_command(&c, &["rpush", "foo", "hello", "world"]).await 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        assert_eq!( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Ok(Value::Integer(3)), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            run_command(&c, &["linsert", "foo", "after", "world", "there1"]).await 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        assert_eq!( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Ok(Value::Integer(4)), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            run_command(&c, &["linsert", "foo", "before", "world", "there2"]).await 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        assert_eq!( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Ok(Value::Array(vec![ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                Value::Blob("hello".into()), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                Value::Blob("there2".into()), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                Value::Blob("world".into()), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                Value::Blob("there1".into()), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ])), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            run_command(&c, &["lrange", "foo", "0", "-1"]).await, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    #[tokio::test] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    async fn linsert_not_found() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let c = create_connection(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        assert_eq!( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Ok(Value::Integer(2)), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            run_command(&c, &["rpush", "foo", "hello", "world"]).await 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        assert_eq!( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Ok(Value::Integer(-1)), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            run_command(&c, &["linsert", "foo", "after", "worldx", "there"]).await 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        assert_eq!( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Ok(Value::Integer(-1)), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            run_command(&c, &["linsert", "foo", "before", "worldx", "there"]).await 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    #[tokio::test] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     async fn llen() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         let c = create_connection(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -478,6 +712,95 @@ mod test { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     #[tokio::test] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    async fn lpos_single_match() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let c = create_connection(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        assert_eq!( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Ok(Value::Integer(11)), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            run_command( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                &c, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                &["RPUSH", "mylist", "a", "b", "c", "d", "1", "2", "3", "4", "3", "3", "3"] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            .await 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        assert_eq!( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Ok(Value::Integer(6)), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            run_command(&c, &["lpos", "mylist", "3"]).await 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    #[tokio::test] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    async fn lpos_single_skip() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let c = create_connection(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        assert_eq!( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Ok(Value::Integer(11)), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            run_command( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                &c, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                &["RPUSH", "mylist", "a", "b", "c", "d", "1", "2", "3", "4", "3", "3", "3"] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            .await 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        assert_eq!( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Ok(Value::Integer(8)), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            run_command(&c, &["lpos", "mylist", "3", "rank", "2"]).await 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    #[tokio::test] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    async fn lpos_single_skip_max_len() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let c = create_connection(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        assert_eq!( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Ok(Value::Integer(11)), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            run_command( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                &c, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                &["RPUSH", "mylist", "a", "b", "c", "d", "1", "2", "3", "4", "3", "3", "3"] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            .await 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        assert_eq!( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Ok(Value::Null), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            run_command(&c, &["lpos", "mylist", "3", "rank", "2", "maxlen", "7"]).await 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    #[tokio::test] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    async fn lpos_not_found() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let c = create_connection(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        assert_eq!( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Ok(Value::Array(vec![])), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            run_command(&c, &["lpos", "mylist", "3", "count", "5", "maxlen", "9"]).await 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        assert_eq!( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Ok(Value::Null), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            run_command(&c, &["lpos", "mylist", "3"]).await 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    #[tokio::test] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    async fn lpos() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let c = create_connection(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        assert_eq!( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Ok(Value::Integer(11)), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            run_command( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                &c, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                &["RPUSH", "mylist", "a", "b", "c", "d", "1", "2", "3", "4", "3", "3", "3"] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            .await 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        assert_eq!( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Ok(Value::Array(vec![ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                Value::Integer(6), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                Value::Integer(8), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                Value::Integer(9), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ])), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            run_command(&c, &["lpos", "mylist", "3", "count", "5", "maxlen", "9"]).await 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    #[tokio::test] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     async fn lpush() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         let c = create_connection(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 |