ralpha / pdf_signing

Rust library for adding signatures and digitally sign PDF documents.
Apache License 2.0
20 stars 8 forks source link

Failed to select a version for the requirement `lopdf = "^0.27.0"` #4

Closed lusajo143 closed 1 week ago

lusajo143 commented 1 year ago

Hi @ralpha , I have been trying to run your example after creating all required certs, unfortunately I'm getting this error.

error: failed to select a version for the requirement `lopdf = "^0.27.0"`
candidate versions found which didn't match: 0.29.0
location searched: Git repository https://github.com/J-F-Liu/lopdf?branch=master
required by package `pdf_signing v0.1.0 (/path/to/project/folder)`

I have tried to change lopdf version to 0.29.0, I'm getting the following errors.

error[E0631]: type mismatch in function arguments
   --> src/image_xobject.rs:172:73
    |
172 |         let bbox: lopdf::Object = Array(identity_matrix.into_iter().map(Real).collect());
    |                                                                     --- ^^^^
    |                                                                     |   |
    |                                                                     |   expected due to this
    |                                                                     |   found signature defined here
    |                                                                     required by a bound introduced by this call
    |
    = note: expected function signature `fn(f64) -> _`
               found function signature `fn(f32) -> _`
note: required by a bound in `map`
   --> /home/egovridc/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/iter/traits/iterator.rs:779:12
    |
779 |         F: FnMut(Self::Item) -> B,
    |            ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `map`

error[E0599]: the method `collect` exists for struct `std::iter::Map<std::vec::IntoIter<f64>, fn(f32) -> lopdf::Object {lopdf::Object::Real}>`, but its trait bounds were not satisfied
   --> src/image_xobject.rs:172:79
    |
172 |         let bbox: lopdf::Object = Array(identity_matrix.into_iter().map(Real).collect());
    |                                                                               ^^^^^^^ method cannot be called on `std::iter::Map<std::vec::IntoIter<f64>, fn(f32) -> lopdf::Object {lopdf::Object::Real}>` due to unsatisfied trait bounds
    |
   ::: /home/egovridc/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/iter/adapters/map.rs:61:1
    |
61  | pub struct Map<I, F> {
    | -------------------- doesn't satisfy `_: Iterator`
    |
    = note: the following trait bounds were not satisfied:
            `<fn(f32) -> lopdf::Object {lopdf::Object::Real} as FnOnce<(f64,)>>::Output = _`
            which is required by `std::iter::Map<std::vec::IntoIter<f64>, fn(f32) -> lopdf::Object {lopdf::Object::Real}>: Iterator`
            `fn(f32) -> lopdf::Object {lopdf::Object::Real}: FnMut<(f64,)>`
            which is required by `std::iter::Map<std::vec::IntoIter<f64>, fn(f32) -> lopdf::Object {lopdf::Object::Real}>: Iterator`
            `std::iter::Map<std::vec::IntoIter<f64>, fn(f32) -> lopdf::Object {lopdf::Object::Real}>: Iterator`
            which is required by `&mut std::iter::Map<std::vec::IntoIter<f64>, fn(f32) -> lopdf::Object {lopdf::Object::Real}>: Iterator`

error[E0599]: no method named `as_f64` found for enum `lopdf::Object` in the current scope
   --> src/signature_image.rs:134:47
    |
134 | ...                   x1: child_rect[0].as_f64()?,
    |                                         ^^^^^^ help: there is an associated function with a similar name: `as_i64`

error[E0599]: no method named `as_f64` found for enum `lopdf::Object` in the current scope
   --> src/signature_image.rs:135:47
    |
135 | ...                   y1: child_rect[1].as_f64()?,
    |                                         ^^^^^^ help: there is an associated function with a similar name: `as_i64`

error[E0599]: no method named `as_f64` found for enum `lopdf::Object` in the current scope
   --> src/signature_image.rs:136:47
    |
136 | ...                   x2: child_rect[2].as_f64()?,
    |                                         ^^^^^^ help: there is an associated function with a similar name: `as_i64`

error[E0599]: no method named `as_f64` found for enum `lopdf::Object` in the current scope
   --> src/signature_image.rs:137:47
    |
137 | ...                   y2: child_rect[3].as_f64()?,
    |                                         ^^^^^^ help: there is an associated function with a similar name: `as_i64`

Some errors have detailed explanations: E0599, E0631.
For more information about an error, try `rustc --explain E0599`.
error: could not compile `pdf_signing` due to 6 previous errors
cihansakman commented 2 months ago

I got the same problems and handled to solve it by changing the code a little bit. Since the project has not been developed more then 2 years, it has some mismatches with the loadpdf library. I first try to upgrade it to 0.33 but it didn't work so I also used the 0.29 version and works with the following changes.

The first error occurs because it's trying to map f64 values using a function (Real) that expects f32. Simply convert the f64 values to f32 before passing them to the Real function.

let identity_matrix: Vec<f64> = vec![1.0, 0.0, 0.0, 1.0, 0.0, 0.0];
let bbox: lopdf::Object = Array(
    identity_matrix
        .into_iter()
        .map(|val| Real(val as f32))  // Convert f64 to f32
        .collect()
);

The second issue occurs because there is no such method anymore... To extract numeric values from lopdf::Object, you should handle existing variants, such as Real for floating-point numbers and Integer for integers. Here's a helper method:

fn extract_f64(obj: &lopdf::Object) -> Result<f64, Error> {
    match obj {
        lopdf::Object::Real(val) => Ok(*val as f64),  // Handle Real variant
        lopdf::Object::Integer(val) => Ok(*val as f64),  // Handle Integer variant
        _ => Err(Error::Other("Expected a numeric value.".to_owned())),  // Handle non-numeric variants
    }
}

And then you can revise the code as follow:

let rect = Some(Rectangle {
    x1: extract_f64(&child_rect[0])?,
    y1: extract_f64(&child_rect[1])?,
    x2: extract_f64(&child_rect[2])?,
    y2: extract_f64(&child_rect[3])?,
});
ralpha commented 1 week ago

I just updated the repo and everything should work now. The problem was because of dependencies that where not on crates.io yet. And since then the git repo's changed a lot. Should be fixed now and should keep working.