Echo Writes Code

errors.hpp

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
#ifndef CRUCIBLE_UNIX_ERRORS_HPP
#define CRUCIBLE_UNIX_ERRORS_HPP

#include "crucible/core/errors.hpp"
#include "crucible/core/result.inl"

#include <functional>
#include <optional>
#include <string>
#include <variant>

namespace crucible::unix::errors {
  class HostError final : public core::errors::AbstractError {
  public:
    HostError();

    ~HostError() override;

    [[nodiscard]]
    auto format() const -> std::string override;

    [[nodiscard]]
    auto source() const & -> std::optional<std::reference_wrapper<core::errors::AbstractError const>> override;

  private:
    int my_error_code { 0 };
  };

  struct FStatFailed final {
    HostError host_error {};
  };

  struct MkdirFailed final {
    HostError host_error {};
  };

  struct OpenFailed final {
    HostError host_error {};
  };

  struct OpenDirFailed final {
    HostError host_error {};
  };

  struct ReadFailed final {
    HostError host_error {};
  };

  struct ReadDirFailed final {
    HostError host_error {};
  };

  struct RmdirFailed final {
    HostError host_error {};
  };

  struct StatFailed final {
    HostError host_error {};
  };

  struct UnlinkFailed final {
    HostError host_error {};
  };

  struct WriteFailed final {
    HostError host_error {};
  };

  struct IncompleteRead final {
  };

  struct IncompleteWrite final {
  };

  struct NegativeFileSize final {
  };

  class UnixError final : public core::errors::AbstractError {
  public:
    explicit UnixError(FStatFailed const &variant);

    explicit UnixError(MkdirFailed const &variant);

    explicit UnixError(OpenFailed const &variant);

    explicit UnixError(OpenDirFailed const &variant);

    explicit UnixError(ReadFailed const &variant);

    explicit UnixError(ReadDirFailed const &variant);

    explicit UnixError(RmdirFailed const &variant);

    explicit UnixError(StatFailed const &variant);

    explicit UnixError(UnlinkFailed const &variant);

    explicit UnixError(WriteFailed const &variant);

    explicit UnixError(IncompleteRead const &variant);

    explicit UnixError(IncompleteWrite const &variant);

    explicit UnixError(NegativeFileSize const &variant);

    ~UnixError() override;

    template<typename T>
    [[nodiscard]]
    auto is() const -> bool {
      return std::holds_alternative<T>(my_variant);
    }

    [[nodiscard]]
    auto format() const -> std::string override;

    [[nodiscard]]
    auto source() const & -> std::optional<std::reference_wrapper<core::errors::AbstractError const>> override;

  private:
    std::variant<FStatFailed, MkdirFailed, OpenFailed, OpenDirFailed, ReadFailed, ReadDirFailed, RmdirFailed, StatFailed, UnlinkFailed, WriteFailed, IncompleteRead, IncompleteWrite, NegativeFileSize> my_variant;
  };

  template<typename T>
  using UnixResult = core::result::Result<UnixError, T>;
}

#endif // CRUCIBLE_UNIX_ERRORS_HPP