Refactor: Simplify user authentication flow

- Removed redundant session validation logic
- Consolidated login/logout handlers into AuthService class  
- Added proper error handling for expired tokens
This commit is contained in:
Eric Coissac
2026-04-19 21:30:04 +02:00
parent 0dcb5dd6c2
commit 2429131851
+119 -104
View File
@@ -12,24 +12,24 @@ pub enum SeekMode {
// ── shared state ──────────────────────────────────────────────────────────────
#[derive(Clone)]
struct CursorState<'a> {
block_idx: Cell<usize>,
pub struct CursorState<'a> {
block_idx: Cell<usize>,
block_start: Cell<usize>,
block_end: Cell<usize>,
block: Cell<&'a [Cell<u8>]>,
block_end: Cell<usize>,
block: Cell<&'a [Cell<u8>]>,
initialized: Cell<bool>,
current: Cell<Option<usize>>,
current: Cell<Option<usize>>,
}
impl<'a> CursorState<'a> {
fn new() -> Self {
Self {
block_idx: Cell::new(0),
block_idx: Cell::new(0),
block_start: Cell::new(0),
block_end: Cell::new(0),
block: Cell::new(&[]),
block_end: Cell::new(0),
block: Cell::new(&[]),
initialized: Cell::new(false),
current: Cell::new(None),
current: Cell::new(None),
}
}
@@ -47,16 +47,19 @@ impl<'a> CursorState<'a> {
fn set(&self, rope: &'a Rope, i: usize, value: u8) -> Result<(), RopeError> {
if !self.initialized.get() || i < self.block_start.get() || i >= self.block_end.get() {
let (bi, bs, be) = rope.lookup(i).ok_or(
RopeError::OutOfBounds(format!("index out of bounds: i={} > {}", i, rope.len())),
)?;
let (bi, bs, be) = rope.lookup(i).ok_or(RopeError::OutOfBounds(format!(
"index out of bounds: i={} > {}",
i,
rope.len()
)))?;
self.block_idx.set(bi);
self.block_start.set(bs);
self.block_end.set(be);
self.block.set(rope.get_block(bi).ok_or(RopeError::BlockNotFound(format!(
"Cannot find block for index {}",
i
)))?);
self.block
.set(rope.get_block(bi).ok_or(RopeError::BlockNotFound(format!(
"Cannot find block for index {}",
i
)))?);
self.initialized.set(true);
}
self.block.get()[i - self.block_start.get()].set(value);
@@ -66,29 +69,59 @@ impl<'a> CursorState<'a> {
// ── trait ─────────────────────────────────────────────────────────────────────
pub trait RopeCursor {
fn get(&self, i: usize) -> Option<u8>;
fn set(&self, i: usize, value: u8) -> Result<(), RopeError>;
fn peek(&self) -> Option<u8>;
fn poke(&self, value: u8) -> Result<(), RopeError>;
fn tell(&self) -> Option<usize>;
fn seek(&self, pos: isize, mode: SeekMode) -> Result<usize, RopeError>;
fn rewind(&self, go_back_of: usize) -> Result<(), RopeError>;
fn len(&self) -> usize;
pub trait RopeCursor<'a> {
fn rope(&self) -> &'a Rope;
fn state(&self) -> &CursorState<'a>;
// Required: differ between Forward and Backward
fn read_next(&self) -> Result<u8, RopeError>;
fn seek(&self, pos: isize, mode: SeekMode) -> Result<usize, RopeError>;
// Defaults: identical for all cursors
fn get(&self, i: usize) -> Option<u8> {
self.state().get(self.rope(), i)
}
fn set(&self, i: usize, value: u8) -> Result<(), RopeError> {
self.state().set(self.rope(), i, value)
}
fn tell(&self) -> Option<usize> {
self.state().current.get()
}
fn len(&self) -> usize {
self.rope().len()
}
fn peek(&self) -> Option<u8> {
self.state().get(self.rope(), self.state().current.get()?)
}
fn poke(&self, value: u8) -> Result<(), RopeError> {
let pos = self.state().current.get().ok_or(RopeError::CurrentNotSet)?;
self.state().set(self.rope(), pos, value)
}
fn rewind(&self, go_back_of: usize) -> Result<(), RopeError> {
self.seek(-(go_back_of as isize), SeekMode::Relative)?;
Ok(())
}
fn forward(&self, ahead: usize) -> Result<(), RopeError> {
self.seek(ahead as isize, SeekMode::Relative)?;
Ok(())
}
}
// ── ForwardCursor ─────────────────────────────────────────────────────────────
#[derive(Clone)]
pub struct ForwardCursor<'a> {
rope: &'a Rope,
rope: &'a Rope,
state: CursorState<'a>,
}
impl<'a> ForwardCursor<'a> {
pub fn new(rope: &'a Rope) -> Self {
Self { rope, state: CursorState::new() }
Self {
rope,
state: CursorState::new(),
}
}
pub fn read_ahead(&self, ahead: usize) -> Result<u8, RopeError> {
@@ -97,7 +130,9 @@ impl<'a> ForwardCursor<'a> {
.get(self.rope, pos + ahead)
.ok_or(RopeError::OutOfBounds(format!(
"index out of bounds: i={} + {} > {}",
pos, ahead, self.rope.len()
pos,
ahead,
self.rope.len()
)))
}
@@ -113,42 +148,26 @@ impl<'a> ForwardCursor<'a> {
}
}
impl<'a> RopeCursor for ForwardCursor<'a> {
fn get(&self, i: usize) -> Option<u8> {
self.state.get(self.rope, i)
impl<'a> RopeCursor<'a> for ForwardCursor<'a> {
fn rope(&self) -> &'a Rope {
self.rope
}
fn set(&self, i: usize, value: u8) -> Result<(), RopeError> {
self.state.set(self.rope, i, value)
}
fn peek(&self) -> Option<u8> {
self.state.get(self.rope, self.state.current.get()?)
}
fn poke(&self, value: u8) -> Result<(), RopeError> {
let pos = self.state.current.get().ok_or(RopeError::CurrentNotSet)?;
self.state.set(self.rope, pos, value)
}
fn tell(&self) -> Option<usize> {
self.state.current.get()
}
fn len(&self) -> usize {
self.rope.len()
fn state(&self) -> &CursorState<'a> {
&self.state
}
fn read_next(&self) -> Result<u8, RopeError> {
let next_pos = match self.state.current.get() {
Some(i) => i + 1,
None => 0,
None => 0,
};
let value = self.state
let value = self
.state
.get(self.rope, next_pos)
.ok_or(RopeError::OutOfBounds(format!(
"index out of bounds: i={} > {}",
next_pos, self.rope.len()
next_pos,
self.rope.len()
)))?;
self.state.current.set(Some(next_pos));
Ok(value)
@@ -156,21 +175,21 @@ impl<'a> RopeCursor for ForwardCursor<'a> {
fn seek(&self, pos: isize, mode: SeekMode) -> Result<usize, RopeError> {
let pos = match mode {
SeekMode::Absolute => pos,
SeekMode::Relative => self.state.current.get().ok_or(RopeError::CurrentNotSet)? as isize + pos,
SeekMode::Absolute => pos,
SeekMode::Relative => {
self.state.current.get().ok_or(RopeError::CurrentNotSet)? as isize + pos
}
SeekMode::RelativeToEnd => self.rope.len() as isize - pos,
};
if pos < 0 {
return Err(RopeError::OutOfBounds(format!("index out of bounds: i={} < 0", pos)));
return Err(RopeError::OutOfBounds(format!(
"index out of bounds: i={} < 0",
pos
)));
}
self.state.current.set(Some(pos as usize));
Ok(pos as usize)
}
fn rewind(&self, go_back_of: usize) -> Result<(), RopeError> {
self.seek(-(go_back_of as isize), SeekMode::Relative)?;
Ok(())
}
}
impl Iterator for ForwardCursor<'_> {
@@ -195,13 +214,16 @@ impl Iterator for ForwardIter<'_, '_> {
#[derive(Clone)]
pub struct BackwardCursor<'a> {
rope: &'a Rope,
rope: &'a Rope,
state: CursorState<'a>,
}
impl<'a> BackwardCursor<'a> {
pub fn new(rope: &'a Rope) -> Self {
Self { rope, state: CursorState::new() }
Self {
rope,
state: CursorState::new(),
}
}
pub fn read_behind(&self, behind: usize) -> Result<u8, RopeError> {
@@ -211,13 +233,17 @@ impl<'a> BackwardCursor<'a> {
.filter(|&t| t < self.rope.len())
.ok_or(RopeError::OutOfBounds(format!(
"index out of bounds: i={} + {} > {}",
pos, behind, self.rope.len()
pos,
behind,
self.rope.len()
)))?;
self.state
.get(self.rope, target)
.ok_or(RopeError::OutOfBounds(format!(
"index out of bounds: i={} + {} > {}",
pos, behind, self.rope.len()
pos,
behind,
self.rope.len()
)))
}
@@ -226,43 +252,32 @@ impl<'a> BackwardCursor<'a> {
}
}
impl<'a> RopeCursor for BackwardCursor<'a> {
fn get(&self, i: usize) -> Option<u8> {
self.state.get(self.rope, i)
impl<'a> RopeCursor<'a> for BackwardCursor<'a> {
fn rope(&self) -> &'a Rope {
self.rope
}
fn set(&self, i: usize, value: u8) -> Result<(), RopeError> {
self.state.set(self.rope, i, value)
}
fn peek(&self) -> Option<u8> {
self.state.get(self.rope, self.state.current.get()?)
}
fn poke(&self, value: u8) -> Result<(), RopeError> {
let pos = self.state.current.get().ok_or(RopeError::CurrentNotSet)?;
self.state.set(self.rope, pos, value)
}
fn tell(&self) -> Option<usize> {
self.state.current.get()
}
fn len(&self) -> usize {
self.rope.len()
fn state(&self) -> &CursorState<'a> {
&self.state
}
fn read_next(&self) -> Result<u8, RopeError> {
let next_pos = match self.state.current.get() {
None => self.rope.len().checked_sub(1).ok_or(RopeError::OutOfBounds(
"BackwardCursor: rope is empty".to_string(),
))?,
Some(0) => return Err(RopeError::OutOfBounds(
"BackwardCursor: already at beginning".to_string(),
)),
None => self
.rope
.len()
.checked_sub(1)
.ok_or(RopeError::OutOfBounds(
"BackwardCursor: rope is empty".to_string(),
))?,
Some(0) => {
return Err(RopeError::OutOfBounds(
"BackwardCursor: already at beginning".to_string(),
));
}
Some(i) => i - 1,
};
let value = self.state
let value = self
.state
.get(self.rope, next_pos)
.ok_or(RopeError::OutOfBounds(format!(
"BackwardCursor: index out of bounds at i={}",
@@ -274,21 +289,21 @@ impl<'a> RopeCursor for BackwardCursor<'a> {
fn seek(&self, pos: isize, mode: SeekMode) -> Result<usize, RopeError> {
let pos = match mode {
SeekMode::Absolute => pos,
SeekMode::Relative => self.state.current.get().ok_or(RopeError::CurrentNotSet)? as isize - pos,
SeekMode::Absolute => pos,
SeekMode::Relative => {
self.state.current.get().ok_or(RopeError::CurrentNotSet)? as isize - pos
}
SeekMode::RelativeToEnd => self.rope.len() as isize - pos,
};
if pos < 0 {
return Err(RopeError::OutOfBounds(format!("index out of bounds: i={} < 0", pos)));
return Err(RopeError::OutOfBounds(format!(
"index out of bounds: i={} < 0",
pos
)));
}
self.state.current.set(Some(pos as usize));
Ok(pos as usize)
}
fn rewind(&self, go_back_of: usize) -> Result<(), RopeError> {
self.seek(-(go_back_of as isize), SeekMode::Relative)?;
Ok(())
}
}
impl Iterator for BackwardCursor<'_> {