refactor(core): reorganize module structure
This commit is contained in:
parent
59ab96be98
commit
a6c1863f57
22 changed files with 231 additions and 164 deletions
|
|
@ -4,9 +4,9 @@
|
|||
// CLI test harness for the noctua_core document foundation.
|
||||
|
||||
use clap::{ArgGroup, Parser};
|
||||
use noctua_core::document::command::SessionCommand;
|
||||
use noctua_core::document::manager::{DocumentManager, DocumentState};
|
||||
use noctua_core::document::session::CollectionKind;
|
||||
use noctua_core::document::session::command::SessionCommand;
|
||||
use noctua_core::document::session::data::CollectionKind;
|
||||
use std::path::PathBuf;
|
||||
|
||||
// ── ANSI helpers ──
|
||||
|
|
@ -139,7 +139,7 @@ fn main() {
|
|||
|
||||
exec(
|
||||
&mut mgr,
|
||||
&format!("New session '{session_name}'"),
|
||||
&format!("New browser session '{session_name}'"),
|
||||
SessionCommand::New {
|
||||
name: session_name.clone(),
|
||||
kind: CollectionKind::DirectoryBrowser,
|
||||
|
|
@ -154,7 +154,7 @@ fn main() {
|
|||
);
|
||||
exec(
|
||||
&mut mgr,
|
||||
&format!("Scan directory {}", dir.display()),
|
||||
&format!("Add directory {}", dir.display()),
|
||||
SessionCommand::AddDirectory { dir },
|
||||
);
|
||||
exec(
|
||||
|
|
@ -186,7 +186,7 @@ fn main() {
|
|||
);
|
||||
exec(
|
||||
&mut mgr,
|
||||
&format!("Scan directory {}", path.display()),
|
||||
&format!("Add directory {}", path.display()),
|
||||
SessionCommand::AddDirectory { dir: path },
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,51 +1,13 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// src/document/command.rs
|
||||
//
|
||||
// Command enums for session management and document operations.
|
||||
// Commands that operate on the active document itself.
|
||||
|
||||
use crate::document::session::CollectionKind;
|
||||
use std::path::PathBuf;
|
||||
|
||||
/// Commands operating on sessions and their document collections.
|
||||
/// All collection-mutating commands operate on the active session
|
||||
/// unless they explicitly name a session.
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum SessionCommand {
|
||||
// -- Lifecycle --
|
||||
/// Create a new empty session of the given kind.
|
||||
New { name: String, kind: CollectionKind },
|
||||
/// Open sessions from an existing .ron file.
|
||||
Open { path: PathBuf },
|
||||
/// Switch the active session by name.
|
||||
Select { name: String },
|
||||
|
||||
// -- Collection management --
|
||||
/// Scan a directory and replace the active session's items.
|
||||
AddDirectory { dir: PathBuf },
|
||||
/// Add a single document to the active session.
|
||||
AddDocument { path: PathBuf },
|
||||
/// Copy a document from one session to another.
|
||||
CopyDocument {
|
||||
source: String,
|
||||
target: String,
|
||||
source_index: usize,
|
||||
target_index: usize,
|
||||
},
|
||||
/// Remove a document by index from the active session.
|
||||
RemoveDocument { index: usize },
|
||||
|
||||
// -- Navigation --
|
||||
/// Navigate to the next document in the active session.
|
||||
NextDocument,
|
||||
/// Navigate to the previous document in the active session.
|
||||
PreviousDocument,
|
||||
/// Select a document by index in the active session.
|
||||
SelectDocument { index: usize },
|
||||
}
|
||||
|
||||
/// Commands operating on the active document itself.
|
||||
/// Reserved for future use (rotate, flip, zoom, export, …).
|
||||
/// Commands operating on the active document (zoom, export, annotate, …).
|
||||
///
|
||||
/// The `DocumentManager` dispatches these after resolving which document is
|
||||
/// active – the UI never needs to know the underlying format.
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum DocumentCommand {
|
||||
// Future: Rotate, Flip, Zoom, Export, ...
|
||||
// Reserved for future use: Rotate, Flip, Zoom, Export, Annotate, …
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,38 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// src/document/format.rs
|
||||
//
|
||||
// Single source of truth for document format detection.
|
||||
|
||||
use std::path::Path;
|
||||
|
||||
/// The three document formats Noctua understands.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum DocumentFormat {
|
||||
/// Raster images – anything libcosmic's image crate can decode.
|
||||
Raster,
|
||||
/// Vector graphics (SVG).
|
||||
Vector,
|
||||
/// Portable documents (PDF).
|
||||
Portable,
|
||||
}
|
||||
|
||||
/// Detects the document format from the file extension.
|
||||
///
|
||||
/// Returns `None` for unknown extensions so directory scans can skip
|
||||
/// unsupported files early. At load time the underlying library
|
||||
/// (ImageReader, usvg, pdfium) is the final authority.
|
||||
pub fn detect_format(path: &Path) -> Option<DocumentFormat> {
|
||||
match path
|
||||
.extension()
|
||||
.and_then(|e| e.to_str())
|
||||
.map(|e| e.to_lowercase())
|
||||
.as_deref()
|
||||
{
|
||||
Some("pdf") => Some(DocumentFormat::Portable),
|
||||
Some("svg") => Some(DocumentFormat::Vector),
|
||||
Some("png" | "jpg" | "jpeg" | "webp" | "gif" | "bmp" | "tiff" | "tif") => {
|
||||
Some(DocumentFormat::Raster)
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
|
@ -1,21 +1,56 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// src/document/loader.rs
|
||||
//
|
||||
// Document loading: format dispatch and directory scanning.
|
||||
// Document loading: format detection, format dispatch, and directory scanning.
|
||||
|
||||
use crate::document::format::{detect_format, DocumentFormat};
|
||||
use crate::document::portable::PortableModel;
|
||||
use crate::document::raster::RasterModel;
|
||||
use crate::document::session::{SessionData, SessionItem};
|
||||
use crate::document::vector::VectorModel;
|
||||
use crate::document::{core::PageLayout, DocumentContent};
|
||||
use crate::document::model::{PortableModel, RasterModel, VectorModel};
|
||||
use crate::document::session::data::{SessionData, SessionItem};
|
||||
use crate::document::types::PageLayout;
|
||||
use crate::document::DocumentContent;
|
||||
use crate::error::{Error, Result};
|
||||
use std::path::Path;
|
||||
|
||||
/// The three document formats Noctua understands.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub(crate) enum DocumentFormat {
|
||||
/// Raster images – anything the image crate can decode.
|
||||
Raster,
|
||||
/// Vector graphics (SVG).
|
||||
Vector,
|
||||
/// Portable documents (PDF).
|
||||
Portable,
|
||||
}
|
||||
|
||||
/// Detects the document format from the file extension.
|
||||
///
|
||||
/// Returns `None` for unknown extensions so directory scans can skip
|
||||
/// unsupported files early. At load time the underlying library
|
||||
/// (`ImageReader`, `usvg`, `pdfium`) is the final authority.
|
||||
fn detect_format(path: &Path) -> Option<DocumentFormat> {
|
||||
match path
|
||||
.extension()
|
||||
.and_then(|e| e.to_str())
|
||||
.map(str::to_lowercase)
|
||||
.as_deref()
|
||||
{
|
||||
Some("pdf") => Some(DocumentFormat::Portable),
|
||||
Some("svg") => Some(DocumentFormat::Vector),
|
||||
Some("png" | "jpg" | "jpeg" | "webp" | "gif" | "bmp" | "tiff" | "tif") => {
|
||||
Some(DocumentFormat::Raster)
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Loads a document from a path and returns its content.
|
||||
pub fn load_document(path: &Path) -> Result<DocumentContent> {
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns [`Error::NotFound`] if the path does not exist.
|
||||
/// Returns [`Error::Unsupported`] if the file extension is not recognised.
|
||||
pub(crate) fn load_document(path: &Path) -> Result<DocumentContent> {
|
||||
if !path.exists() {
|
||||
return Err(Error::NotFound(format!("{:?}", path)));
|
||||
return Err(Error::NotFound(format!("{}", path.display())));
|
||||
}
|
||||
|
||||
match detect_format(path) {
|
||||
|
|
@ -51,10 +86,10 @@ pub fn load_document(path: &Path) -> Result<DocumentContent> {
|
|||
}
|
||||
|
||||
/// Scans a directory for supported files and populates the session.
|
||||
pub fn scan_directory_into(session: &mut SessionData, dir: &Path) {
|
||||
pub(crate) fn scan_directory_into(session: &mut SessionData, dir: &Path) {
|
||||
if let Ok(entries) = std::fs::read_dir(dir) {
|
||||
let mut paths: Vec<_> = entries
|
||||
.filter_map(|e| e.ok())
|
||||
.filter_map(std::result::Result::ok)
|
||||
.map(|e| e.path())
|
||||
.filter(|p| p.is_file() && detect_format(p).is_some())
|
||||
.collect();
|
||||
|
|
|
|||
|
|
@ -1,25 +1,22 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// src/document/mod.rs
|
||||
//
|
||||
// Document abstraction and format definitions.
|
||||
// Document abstraction – the public surface of the document subsystem.
|
||||
|
||||
pub mod command;
|
||||
pub mod core;
|
||||
pub mod format;
|
||||
pub mod loader;
|
||||
pub mod manager;
|
||||
pub mod portable;
|
||||
pub mod raster;
|
||||
pub mod model;
|
||||
pub mod session;
|
||||
pub mod store;
|
||||
pub mod vector;
|
||||
pub mod types;
|
||||
|
||||
use self::portable::PortableModel;
|
||||
use self::raster::RasterModel;
|
||||
use self::vector::VectorModel;
|
||||
use self::model::{PortableModel, RasterModel, VectorModel};
|
||||
|
||||
/// Represents the physical content of a loaded document.
|
||||
#[derive(Debug, Clone)]
|
||||
/// The decoded content of a loaded document.
|
||||
///
|
||||
/// This enum is internal to `noctua_core`. The UI only ever sees a `RawImage`
|
||||
/// produced by the render subsystem – it never matches on this type.
|
||||
#[derive(Debug)]
|
||||
pub enum DocumentContent {
|
||||
Raster(RasterModel),
|
||||
Vector(VectorModel),
|
||||
|
|
|
|||
12
core/src/document/model/mod.rs
Normal file
12
core/src/document/model/mod.rs
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// src/document/model/mod.rs
|
||||
//
|
||||
// The three concrete document models Noctua understands.
|
||||
|
||||
pub mod portable;
|
||||
pub mod raster;
|
||||
pub mod vector;
|
||||
|
||||
pub use portable::PortableModel;
|
||||
pub use raster::RasterModel;
|
||||
pub use vector::VectorModel;
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// src/document/portable.rs
|
||||
// src/document/model/portable.rs
|
||||
//
|
||||
// Portable document format model (PDF).
|
||||
|
||||
use crate::document::core::PageLayout;
|
||||
use crate::document::types::PageLayout;
|
||||
use std::path::PathBuf;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// src/document/raster.rs
|
||||
// src/document/model/raster.rs
|
||||
//
|
||||
// Raster image document model (JPEG, PNG, etc.).
|
||||
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// src/document/vector.rs
|
||||
// src/document/model/vector.rs
|
||||
//
|
||||
// Vector image document model (SVG).
|
||||
|
||||
use crate::document::core::ViewBox;
|
||||
use crate::document::types::ViewBox;
|
||||
use std::path::PathBuf;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
45
core/src/document/session/command.rs
Normal file
45
core/src/document/session/command.rs
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// src/document/session/command.rs
|
||||
//
|
||||
// Commands that operate on sessions and their document collections.
|
||||
|
||||
use crate::document::session::data::CollectionKind;
|
||||
use std::path::PathBuf;
|
||||
|
||||
/// Commands operating on sessions and their document collections.
|
||||
///
|
||||
/// All collection-mutating commands operate on the active session
|
||||
/// unless they explicitly name a session.
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum SessionCommand {
|
||||
// Lifecycle
|
||||
/// Create a new empty session of the given kind.
|
||||
New { name: String, kind: CollectionKind },
|
||||
/// Open sessions from an existing .ron file.
|
||||
Open { path: PathBuf },
|
||||
/// Switch the active session by name.
|
||||
Select { name: String },
|
||||
|
||||
// Collection management
|
||||
/// Scan a directory and replace the active session's items.
|
||||
AddDirectory { dir: PathBuf },
|
||||
/// Add a single document to the active session.
|
||||
AddDocument { path: PathBuf },
|
||||
/// Copy a document from one session to another.
|
||||
CopyDocument {
|
||||
source: String,
|
||||
target: String,
|
||||
source_index: usize,
|
||||
target_index: usize,
|
||||
},
|
||||
/// Remove a document by index from the active session.
|
||||
RemoveDocument { index: usize },
|
||||
|
||||
// Navigation
|
||||
/// Navigate to the next document in the active session.
|
||||
NextDocument,
|
||||
/// Navigate to the previous document in the active session.
|
||||
PreviousDocument,
|
||||
/// Select a document by index in the active session.
|
||||
SelectDocument { index: usize },
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// src/document/session.rs
|
||||
// src/document/session/data.rs
|
||||
//
|
||||
// A session is the unit of work in Noctua. It groups a set of document items
|
||||
// under a name and tracks which item is currently active.
|
||||
|
|
@ -42,6 +42,7 @@ pub struct SessionItem {
|
|||
}
|
||||
|
||||
impl SessionItem {
|
||||
#[must_use]
|
||||
pub fn new(path: PathBuf, page_index: usize) -> Self {
|
||||
Self { path, page_index }
|
||||
}
|
||||
|
|
@ -52,8 +53,8 @@ impl SessionItem {
|
|||
pub struct SessionData {
|
||||
pub name: String,
|
||||
pub kind: CollectionKind,
|
||||
/// For DirectoryBrowser: the source directory to scan.
|
||||
/// For DocumentCollection: None (items are managed individually).
|
||||
/// For `DirectoryBrowser`: the source directory to scan.
|
||||
/// For `DocumentCollection`: None (items are managed individually).
|
||||
/// The .ron session file path is tracked separately.
|
||||
#[serde(default)]
|
||||
pub path: Option<PathBuf>,
|
||||
|
|
@ -63,6 +64,7 @@ pub struct SessionData {
|
|||
}
|
||||
|
||||
impl SessionData {
|
||||
#[must_use]
|
||||
pub fn new(
|
||||
name: &str,
|
||||
kind: CollectionKind,
|
||||
11
core/src/document/session/mod.rs
Normal file
11
core/src/document/session/mod.rs
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// src/document/session/mod.rs
|
||||
//
|
||||
// Session subsystem: data model, commands, and persistence.
|
||||
|
||||
pub mod command;
|
||||
pub mod data;
|
||||
pub mod store;
|
||||
|
||||
pub use command::SessionCommand;
|
||||
pub use data::{CollectionKind, SessionData, SessionItem};
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// src/document/store.rs
|
||||
// src/document/session/store.rs
|
||||
//
|
||||
// RON-based persistence for session data: load and save session lists.
|
||||
//
|
||||
|
|
@ -27,23 +27,37 @@
|
|||
// ),
|
||||
// ]
|
||||
|
||||
use crate::document::session::SessionData;
|
||||
use crate::document::session::data::SessionData;
|
||||
use crate::error::{Error, Result};
|
||||
use std::path::Path;
|
||||
|
||||
/// Loads all sessions from a RON file.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns [`Error::Io`] if the file cannot be read.
|
||||
/// Returns [`Error::Session`] if the file cannot be parsed.
|
||||
pub fn load_sessions(path: &Path) -> Result<Vec<SessionData>> {
|
||||
let content = std::fs::read_to_string(path).map_err(Error::Io)?;
|
||||
|
||||
ron::from_str(&content)
|
||||
.map_err(|e| Error::Session(format!("Failed to parse session file {:?}: {}", path, e)))
|
||||
ron::from_str(&content).map_err(|e| {
|
||||
Error::Session(format!(
|
||||
"Failed to parse session file {}: {e}",
|
||||
path.display()
|
||||
))
|
||||
})
|
||||
}
|
||||
|
||||
/// Saves all sessions to a RON file.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns [`Error::Session`] if the sessions cannot be serialized.
|
||||
/// Returns [`Error::Io`] if the file cannot be written.
|
||||
#[allow(dead_code)]
|
||||
pub fn save_sessions(path: &Path, sessions: &[SessionData]) -> Result<()> {
|
||||
let content = ron::ser::to_string_pretty(sessions, ron::ser::PrettyConfig::default())
|
||||
.map_err(|e| Error::Session(format!("Failed to serialize sessions: {}", e)))?;
|
||||
.map_err(|e| Error::Session(format!("Failed to serialize sessions: {e}")))?;
|
||||
|
||||
std::fs::write(path, content).map_err(Error::Io)
|
||||
}
|
||||
17
core/src/document/types/image.rs
Normal file
17
core/src/document/types/image.rs
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// src/document/types/image.rs
|
||||
//
|
||||
// Raw pixel buffer passed from the render subsystem to the UI.
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
/// A decoded, format-independent pixel buffer ready for display.
|
||||
///
|
||||
/// The UI receives this type from the `DocumentManager` and never needs to
|
||||
/// know which document format (PDF, SVG, raster) produced it.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct RawImage {
|
||||
pub data: Arc<Vec<u8>>,
|
||||
pub width: u32,
|
||||
pub height: u32,
|
||||
}
|
||||
|
|
@ -1,17 +1,13 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// src/document/core.rs
|
||||
// src/document/types/layout.rs
|
||||
//
|
||||
// Core domain models for document representation.
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct RawImage {
|
||||
pub data: Arc<Vec<u8>>,
|
||||
pub width: u32,
|
||||
pub height: u32,
|
||||
}
|
||||
// PageLayout – describes the vertical arrangement of pages in a document.
|
||||
|
||||
/// The computed layout of all pages in a multi-page document.
|
||||
///
|
||||
/// Stores absolute y-offsets for each page so the render subsystem can
|
||||
/// determine which pages are visible at a given scroll position without
|
||||
/// iterating the full list on every frame.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct PageLayout {
|
||||
pub page_starts: Vec<f64>,
|
||||
|
|
@ -21,15 +17,8 @@ pub struct PageLayout {
|
|||
pub max_width: f64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct ViewBox {
|
||||
pub x: f64,
|
||||
pub y: f64,
|
||||
pub width: f64,
|
||||
pub height: f64,
|
||||
}
|
||||
|
||||
impl PageLayout {
|
||||
#[must_use]
|
||||
pub fn new(page_sizes: Vec<(f64, f64)>, gap: f64) -> Self {
|
||||
let mut page_starts = Vec::with_capacity(page_sizes.len());
|
||||
let mut y = 0.0_f64;
|
||||
|
|
@ -43,7 +32,7 @@ impl PageLayout {
|
|||
}
|
||||
}
|
||||
|
||||
let total_height = if !page_sizes.is_empty() { y - gap } else { 0.0 };
|
||||
let total_height = if page_sizes.is_empty() { 0.0 } else { y - gap };
|
||||
|
||||
Self {
|
||||
page_starts,
|
||||
12
core/src/document/types/mod.rs
Normal file
12
core/src/document/types/mod.rs
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// src/document/types/mod.rs
|
||||
//
|
||||
// Shared domain primitives used across the document and render subsystems.
|
||||
|
||||
pub mod image;
|
||||
pub mod layout;
|
||||
pub mod viewbox;
|
||||
|
||||
pub use image::RawImage;
|
||||
pub use layout::PageLayout;
|
||||
pub use viewbox::ViewBox;
|
||||
16
core/src/document/types/viewbox.rs
Normal file
16
core/src/document/types/viewbox.rs
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// src/document/types/viewbox.rs
|
||||
//
|
||||
// ViewBox – describes the visible coordinate space of a vector document.
|
||||
|
||||
/// The coordinate space declared by an SVG `viewBox` attribute.
|
||||
///
|
||||
/// Used by the render subsystem to map document coordinates to screen pixels
|
||||
/// without exposing SVG internals to the UI.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct ViewBox {
|
||||
pub x: f64,
|
||||
pub y: f64,
|
||||
pub width: f64,
|
||||
pub height: f64,
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// src/error/kinds.rs
|
||||
// src/error.rs
|
||||
//
|
||||
// Central error types for Noctua.
|
||||
// Central error and result types for noctua_core.
|
||||
|
||||
use std::fmt;
|
||||
|
||||
|
|
@ -24,11 +24,11 @@ pub enum Error {
|
|||
impl fmt::Display for Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Error::NotFound(msg) => write!(f, "Not found: {}", msg),
|
||||
Error::Unsupported(msg) => write!(f, "Unsupported: {}", msg),
|
||||
Error::Render(msg) => write!(f, "Render error: {}", msg),
|
||||
Error::Session(msg) => write!(f, "Session error: {}", msg),
|
||||
Error::Io(err) => write!(f, "I/O error: {}", err),
|
||||
Error::NotFound(msg) => write!(f, "Not found: {msg}"),
|
||||
Error::Unsupported(msg) => write!(f, "Unsupported: {msg}"),
|
||||
Error::Render(msg) => write!(f, "Render error: {msg}"),
|
||||
Error::Session(msg) => write!(f, "Session error: {msg}"),
|
||||
Error::Io(err) => write!(f, "I/O error: {err}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// src/error/mod.rs
|
||||
//
|
||||
// Central error module – re-exports the shared Error and Result types.
|
||||
|
||||
mod kinds;
|
||||
|
||||
pub use kinds::{Error, Result};
|
||||
|
|
@ -3,6 +3,12 @@
|
|||
//
|
||||
// Public API of the noctua_core library.
|
||||
|
||||
pub mod document;
|
||||
pub mod error;
|
||||
|
||||
pub mod document;
|
||||
pub mod render;
|
||||
|
||||
pub use document::command::DocumentCommand;
|
||||
pub use document::manager::DocumentManager;
|
||||
pub use document::session::SessionCommand;
|
||||
pub use document::types::RawImage;
|
||||
|
|
|
|||
|
|
@ -4,5 +4,4 @@
|
|||
// Rendering subsystem: converts document content into displayable output.
|
||||
|
||||
pub mod converter;
|
||||
pub mod page;
|
||||
pub mod thumbnail;
|
||||
|
|
|
|||
|
|
@ -1,4 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// src/render/page.rs
|
||||
//
|
||||
// Page layout and rendering primitives (scaffold – not yet implemented).
|
||||
Loading…
Add table
Add a link
Reference in a new issue