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
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

/// Result values of attempted ping uploads encoded for FFI use.
///
/// In a perfect world this would live in `glean-ffi`,
/// but because we also want to convert from pure integer values to a proper Rust enum
/// using Rust's `From` and `Into` trait, we need to have it in this crate
/// (The coherence rules don't allow to implement an external trait for an external type).
///
/// Due to restrictions of cbindgen they are re-defined in `glean-core/ffi/src/upload.rs`.
///
/// NOTE:
/// THEY MUST BE THE SAME ACROSS BOTH FILES!
pub mod ffi_upload_result {
    /// A recoverable error.
    pub const UPLOAD_RESULT_RECOVERABLE: u32 = 0x1;

    /// An unrecoverable error.
    pub const UPLOAD_RESULT_UNRECOVERABLE: u32 = 0x2;

    /// A HTTP response code.
    ///
    /// The actual response code is encoded in the lower bits.
    pub const UPLOAD_RESULT_HTTP_STATUS: u32 = 0x8000;
}
use ffi_upload_result::*;

/// The result of an attempted ping upload.
#[derive(Debug)]
pub enum UploadResult {
    /// A recoverable failure.
    ///
    /// During upload something went wrong,
    /// e.g. the network connection failed.
    /// The upload should be retried at a later time.
    RecoverableFailure,

    /// An unrecoverable upload failure.
    ///
    /// A possible cause might be a malformed URL.
    UnrecoverableFailure,

    /// A HTTP response code.
    ///
    /// This can still indicate an error, depending on the status code.
    HttpStatus(u32),
}

impl From<u32> for UploadResult {
    fn from(status: u32) -> Self {
        match status {
            status if (status & UPLOAD_RESULT_HTTP_STATUS) == UPLOAD_RESULT_HTTP_STATUS => {
                // Extract the status code from the lower bits.
                let http_status = status & !UPLOAD_RESULT_HTTP_STATUS;
                UploadResult::HttpStatus(http_status)
            }
            UPLOAD_RESULT_RECOVERABLE => UploadResult::RecoverableFailure,
            UPLOAD_RESULT_UNRECOVERABLE => UploadResult::UnrecoverableFailure,

            // Any unknown result code is treated as unrecoverable.
            _ => UploadResult::UnrecoverableFailure,
        }
    }
}