This commit is contained in:
18
LICENSE
Normal file
18
LICENSE
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2025 woggioni
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||||
|
associated documentation files (the "Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the
|
||||||
|
following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all copies or substantial
|
||||||
|
portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
|
||||||
|
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
|
||||||
|
EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||||
|
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
@@ -1,153 +0,0 @@
|
|||||||
use std::mem;
|
|
||||||
use std::ptr;
|
|
||||||
|
|
||||||
pub struct List<T> {
|
|
||||||
list_head: Option<Box<Node<T>>>,
|
|
||||||
list_tail: Rawlink<Node<T>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Rawlink<T> { p: *mut T }
|
|
||||||
|
|
||||||
impl<T> Copy for Rawlink<T> {}
|
|
||||||
|
|
||||||
impl<T> Clone for Rawlink<T> {
|
|
||||||
fn clone(&self) -> Self { Rawlink { p: self.p } }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Node<T> {
|
|
||||||
next: Option<Box<Node<T>>>,
|
|
||||||
prev: Rawlink<Node<T>>,
|
|
||||||
value: T,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> List<T> {
|
|
||||||
pub fn is_empty(&self) -> bool {
|
|
||||||
self.list_head.is_none()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn len(&self) -> usize {
|
|
||||||
let mut node = &self.list_head;
|
|
||||||
let mut i = 0;
|
|
||||||
loop {
|
|
||||||
match *node {
|
|
||||||
Some(ref n) => {
|
|
||||||
i+=1;
|
|
||||||
node=&n.next;
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Create an empty DList
|
|
||||||
pub fn new() -> List<T> {
|
|
||||||
List{list_head: None, list_tail: Rawlink::none()}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn push_front(&mut self, elt: T) {
|
|
||||||
self.push_front_node(Box::new(Node::new(elt)))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn push_front_node(&mut self, mut new_head: Box<Node<T>>) {
|
|
||||||
match self.list_head {
|
|
||||||
None => {
|
|
||||||
self.list_tail = Rawlink::some(&mut new_head);
|
|
||||||
new_head.prev = Rawlink::none();
|
|
||||||
self.list_head = Some(new_head);
|
|
||||||
}
|
|
||||||
Some(ref mut head) => {
|
|
||||||
new_head.prev = Rawlink::none();
|
|
||||||
head.prev = Rawlink::some(&mut new_head);
|
|
||||||
mem::swap(head, &mut new_head);
|
|
||||||
head.next = Some(new_head);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Provide a forward iterator
|
|
||||||
#[inline]
|
|
||||||
pub fn iter<'a>(&'a self) -> ListIterator<'a, T> {
|
|
||||||
ListIterator{nelem: self.len(), head: &self.list_head, tail: self.list_tail}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> Node<T> {
|
|
||||||
fn new(v: T) -> Node<T> {
|
|
||||||
Node{value: v, next: None, prev: Rawlink::none()}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Rawlink is a type like Option<T> but for holding a raw pointer
|
|
||||||
impl<T> Rawlink<T> {
|
|
||||||
/// Like Option::None for Rawlink
|
|
||||||
fn none() -> Rawlink<T> {
|
|
||||||
Rawlink{p: ptr::null_mut()}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Like Option::Some for Rawlink
|
|
||||||
fn some(n: &mut T) -> Rawlink<T> {
|
|
||||||
Rawlink{p: n as *mut T}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Convert the `Rawlink` into an Option value
|
|
||||||
fn resolve_immut<'a>(&self) -> Option<&'a T> {
|
|
||||||
unsafe { self.p.as_ref() }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Convert the `Rawlink` into an Option value
|
|
||||||
fn resolve<'a>(&mut self) -> Option<&'a mut T> {
|
|
||||||
unsafe { self.p.as_mut() }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return the `Rawlink` and replace with `Rawlink::none()`
|
|
||||||
fn take(&mut self) -> Rawlink<T> {
|
|
||||||
mem::replace(self, Rawlink::none())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct ListIterator<'a, T: 'a> {
|
|
||||||
head: &'a Option<Box<Node<T>>>,
|
|
||||||
tail: Rawlink<Node<T>>,
|
|
||||||
nelem: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, A> Iterator for ListIterator<'a, A> {
|
|
||||||
type Item = &'a A;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn next(&mut self) -> Option<&'a A> {
|
|
||||||
if self.nelem == 0 {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
self.head.as_ref().map(|head| {
|
|
||||||
self.nelem -= 1;
|
|
||||||
self.head = &head.next;
|
|
||||||
&head.value
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
|
||||||
(self.nelem, Some(self.nelem))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, A> DoubleEndedIterator for ListIterator<'a, A> {
|
|
||||||
#[inline]
|
|
||||||
fn next_back(&mut self) -> Option<&'a A> {
|
|
||||||
if self.nelem == 0 {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
let tmp = self.tail.resolve_immut();
|
|
||||||
tmp.as_ref().map(|prev| {
|
|
||||||
self.nelem -= 1;
|
|
||||||
self.tail = prev.prev;
|
|
||||||
&prev.value
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
}
|
|
55
src/test.rs
55
src/test.rs
@@ -1,55 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
use std::collections::HashMap;
|
|
||||||
|
|
||||||
// This struct has one lifetime parameter, 'src. The name is only used within the struct's definition.
|
|
||||||
#[derive(Debug)]
|
|
||||||
struct Config<'src> {
|
|
||||||
hostname: &'src str,
|
|
||||||
username: &'src str,
|
|
||||||
}
|
|
||||||
|
|
||||||
// This function also has a lifetime parameter, 'cfg. 'cfg is attached to the "config" parameter, which
|
|
||||||
// establishes that the data in "config" lives at least as long as the 'cfg lifetime.
|
|
||||||
// The returned struct also uses 'cfg for its lifetime, so it can live at most as long as 'cfg.
|
|
||||||
fn parse_config<'cfg>(config: &'cfg str) -> Config<'cfg> {
|
|
||||||
let key_values: HashMap<_, _> = config
|
|
||||||
.lines()
|
|
||||||
.filter(|line| !line.starts_with('#'))
|
|
||||||
.filter_map(|line| line.split_once('='))
|
|
||||||
.map(|(key, value)| (key.trim(), value.trim()))
|
|
||||||
.collect();
|
|
||||||
Config {
|
|
||||||
hostname: key_values["hostname"],
|
|
||||||
username: key_values["username"],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// fn main() {
|
|
||||||
// let config = parse_config(
|
|
||||||
// r#"hostname = foobar
|
|
||||||
// username=barfoo"#,
|
|
||||||
// );
|
|
||||||
// println!("Parsed config: {:#?}", config);
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
struct Foo {}
|
|
||||||
|
|
||||||
fn foo<T>(v : &[T]) {
|
|
||||||
for el in v.into_iter() {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// fn foo2(v : &mut Vec<Vec<isize>>) {
|
|
||||||
// let first = &v[0];
|
|
||||||
// let second = &mut v[1];
|
|
||||||
|
|
||||||
// second[0] = first[1] + second[2];
|
|
||||||
// }
|
|
||||||
fn main() {
|
|
||||||
let s = String::from("🤑😂🤩🤬");
|
|
||||||
let c= s.chars().nth(1).unwrap();
|
|
||||||
println!("{}", c);
|
|
||||||
}
|
|
Reference in New Issue
Block a user