1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
//! # c3dio - Pure Rust C3D Parser
//! This crate provides a parser for C3D files.
//! C3D is a binary file format used to store motion capture data.
//! The format is described in the [C3D file format documentation](https://www.c3d.org/HTML/default.htm).
//!
//! # Examples
//! ```
//! use c3dio::prelude::*;
//!
//! let c3d = C3d::load("tests/data/short.c3d");
//! assert!(c3d.is_ok());
//! ```

use std::path::PathBuf;
use std::{error::Error, fmt};

#[path = "analog.rs"]
pub mod analog;
#[path = "c3d.rs"]
pub mod c3d;
#[path = "data.rs"]
pub mod data;
#[path = "events.rs"]
pub mod events;
#[path = "forces.rs"]
pub mod forces;
#[path = "manufacturer.rs"]
pub mod manufacturer;
#[path = "parameters.rs"]
pub mod parameters;
#[path = "points.rs"]
pub mod points;
#[path = "processor.rs"]
mod processor;
#[path = "seg.rs"]
pub mod seg;

#[path = "file_formats/mod.rs"]
pub mod file_formats;

use analog::Analog;
use events::Events;
use forces::Forces;
use manufacturer::Manufacturer;
use parameters::{Parameter, Parameters};
use points::Points;
use processor::Processor;
use seg::Seg;

pub mod prelude {
    pub use crate::{parameters::ParameterData, C3d, C3dIoError, C3dParseError};
}

/// Reports errors that occurred while parsing a C3D file.
/// The error type is returned by the `load` and `from_bytes` methods.
#[derive(Debug)]
pub enum C3dParseError {
    ReadError(std::io::Error),
    InsufficientBlocks(String),
    InvalidHeaderStartBlock,
    InvalidParameterStartBlock,
    InvalidParameterData,
    InvalidDataStartBlock,
    InvalidProcessorType,
    InvalidDataType,
    InvalidParametersOffset,
    MissingGroup(String),
    MissingParameter(String),
    InvalidGroupId,
    MissingPointScale,
    FileNotOpen,
    NotEnoughData,
    InvalidNextParameter,
    TooManyEvents(i16),
    NumFramesMismatch(usize, usize),
    GroupNotFound(String),
    ParameterNotFound(String, String),
    RequiredParameterNotFound(String),
    InvalidData(Parameter, String),
    InvalidParameterFormat(String),
    AnalogOffsetScaleMismatch,
    InsufficientAnalogOffsets,
    InvalidParameterDimensions(String),
    InvalidParameterType(String),
    InvalidEventLabel(String, String),
    MissingEventTime(usize),
    MissingEventLabel(usize),
    NoParameterTimeEvents,
    HeaderNotParsed,
}

impl Error for C3dParseError {}
impl fmt::Display for C3dParseError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "C3dParseError: {:?}", self)
    }
}

#[derive(Debug)]
pub enum C3dIoError {
    WriteError(PathBuf, std::io::Error),
    InvalidFileExtension(String),
    InvalidFilePath(PathBuf),
    WriteHeaderError(std::io::Error),
    WriteParametersError(std::io::Error),
    WriteDataError(std::io::Error),
    GroupNameTooLong(String),
    GroupNameNotAscii(String),
    GroupDescriptionTooLong(String),
    ParameterNameTooLong(String),
    ParameterNameNotAscii(String),
    InvalidParameterDimensions(String),
    ParameterDescriptionTooLong(String),
    InvalidForcePlatformInfo(String),
}

impl Error for C3dIoError {}
impl fmt::Display for C3dIoError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "C3dIoError: {:?}", self)
    }
}

/// Represents a parsed C3D file.
/// The file can be read from disk or from memory.
///
/// # Examples
///
/// ```
/// use c3dio::prelude::*;
///
/// let c3d = C3d::load("tests/data/short.c3d");
/// assert!(c3d.is_ok());
/// ```
#[derive(Debug)]
pub struct C3d {
    pub parameters: Parameters,
    processor: Processor,
    pub points: Points,
    pub analog: Analog,
    pub events: Events,
    pub manufacturer: Manufacturer,
    pub seg: Seg,
    pub forces: Forces,
    header_bytes: [u8; 512],
}